summaryrefslogtreecommitdiff
path: root/Master/texmf-dist
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r--Master/texmf-dist/doc/latex/prerex/README105
-rw-r--r--Master/texmf-dist/doc/latex/prerex/chart.html22
-rw-r--r--Master/texmf-dist/doc/latex/prerex/chart.pdfbin0 -> 14318 bytes
-rw-r--r--Master/texmf-dist/doc/latex/prerex/chart.pngbin0 -> 25135 bytes
-rw-r--r--Master/texmf-dist/doc/latex/prerex/chart.tex70
-rw-r--r--Master/texmf-dist/doc/latex/prerex/doc/intro.pdfbin0 -> 237241 bytes
-rw-r--r--Master/texmf-dist/doc/latex/prerex/doc/intro.tex944
-rw-r--r--Master/texmf-dist/doc/latex/prerex/doc/introFonts.pngbin0 -> 6827 bytes
-rw-r--r--Master/texmf-dist/doc/latex/prerex/doc/introchart1.tex58
-rw-r--r--Master/texmf-dist/doc/latex/prerex/doc/introchart2.tex45
-rw-r--r--Master/texmf-dist/doc/latex/prerex/doc/prerex.pdfbin0 -> 183439 bytes
-rw-r--r--Master/texmf-dist/doc/latex/prerex/doc/prerex.sty.7437
-rw-r--r--Master/texmf-dist/doc/latex/prerex/doc/prerex.tex524
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/README62
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.10.patch291
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.8.patch292
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.9.patch291
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.0.3.patch332
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.0.4.patch332
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.0.patch341
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.1.patch341
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.2.patch326
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.3.patch323
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.4.patch323
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.2.0.patch318
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.3.0.patch334
-rw-r--r--Master/texmf-dist/doc/latex/prerex/patches/okular-4.4.0.patch329
-rw-r--r--Master/texmf-dist/doc/latex/prerex/prerex-6.0.1.tar.gzbin0 -> 103611 bytes
-rw-r--r--Master/texmf-dist/doc/latex/prerex/vprerex-6.0.tar.gzbin0 -> 15162 bytes
-rw-r--r--Master/texmf-dist/tex/latex/prerex/prerex.sty597
30 files changed, 7037 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/prerex/README b/Master/texmf-dist/doc/latex/prerex/README
new file mode 100644
index 00000000000..7aaa39ac3b8
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/README
@@ -0,0 +1,105 @@
+prerex, version 6.0: Macros for prerequisite charts, with associated
+editor and viewer applications.
+
+This package consists of
+
+ prerex.sty
+ a LaTeX package for producing charts of course nodes
+ linked by arrows representing pre- and co-requisites,
+
+ prerex
+ an interactive program for creating and editing chart
+ descriptions, and
+
+ vprerex ("visual prerex", formerly called "previewer")
+ a GUI and previewer for prerex.
+
+The implementation of prerex.sty is built on pgf, so that it may
+be used equally happily with latex or pdflatex; prerex is written in C
+and vprerex is written in C++ using the Qt-4 toolkit and the poppler
+library.
+
+See chart.{pdf,html} for a small example of a prerequisite chart and
+real-life examples at
+
+http://www.cs.queensu.ca/students/undergraduate/prerequisites/
+
+Prerequisite charts are useful to students selecting courses and
+planning their programs, and to faculty and staff advising students
+and managing curriculum development. Conventional sources of course,
+program and timetable information are rarely in a user-friendly format.
+Faculty and staff advisors, being already fairly familiar with their
+courses and programs, often do not appreciate how inconvenient it is
+for students to access all the information they need to make course
+choices.
+
+The crucial tool in the prerex suite is "prerex.sty", a macro package
+that defines a "chart" environment and commands to specify construction
+of course boxes and directed arrows between them.
+
+prerex.sty depends on
+
+ pgf (and add-on tikz), version 1.18 or higher
+ multido
+ relsize
+ calc
+ ifthen
+ zref-savepos
+ hyperref
+
+The use of pgf means that Postscript processing is not required;
+either pdflatex or latex -> dvips [ -> ps2pdf ] may be used.
+
+Installation of prerex.sty:
+
+ + copy prerex.sty to your-texmf-tree/tex/latex/misc
+ + copy doc/prerex.{tex,pdf} to your-texmf-tree/doc/latex/misc
+ + if necessary, refresh the TeX database (e.g., texhash)
+ + copy doc/prerex.sty.7 to sub-directory man7 of a man directory on your
+ MANPATH
+ + test by doing
+
+ man 7 prerex.sty
+ pdflatex chart.tex
+
+See doc/prerex.pdf for detailed documentation.
+
+The prerex editor allows interactive editing of the chart environments
+of LaTeX source files. It supports add, remove, cut-and-paste, and edit
+operations on course boxes and arrows, and vertical or horizontal shifts
+of the whole diagram or selected sets of course boxes. When a course
+box is moved, the arrows into and out of it automatically follow.
+To install:
+
+ tar zxvf prerex-6.0.tar.gz
+ cd prerex-6.0
+ ./configure --help
+ ./configure [options]
+ make
+ sudo make install
+
+The effects of editing operations may be observed in any PDF viewer.
+The vprerex (visual prerex) application included in the prerex suite
+is a GUI and viewer for the prerex editor. It may be used just as a
+minimalistic viewer of arbitrary PDF files but supports editing of
+charts generated using prerex.sty by allowing coordinates of course
+boxes, arrows, and background points to be conveyed back to the prerex
+editor command-line using the clipboard.
+
+See the INSTALL in the tarball for installation instructions.
+
+An alternative is to use a version of kpdf/okular (PDF viewers in KDE)
+that has been patched to provide the same access to chart coordinates.
+The "patches" sub-directory provides patches for several recent
+versions of kpdf (KDE-3) and okular (KDE-4). See patches/README for
+instructions.
+
+See the file doc/intro.pdf for an overview of the prerex system.
+
+prerex.sty, README.prerex, prerex.1, prerex.5, prerex.sty.7, prerex.tex
+and chart.tex may be modified and distributed according to the terms of
+the LaTeX Project Public License.
+
+The source files for prerex, vprerex, and the kpdf/okular patches may
+be modified and distributed according to the terms of the GNU General
+Public Licence (version 2).
diff --git a/Master/texmf-dist/doc/latex/prerex/chart.html b/Master/texmf-dist/doc/latex/prerex/chart.html
new file mode 100644
index 00000000000..7f51a46f450
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/chart.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html><head><title></title></head><body>
+<div class="center"><img src="chart.png" usemap="#chart" ismap border=0></div>
+<map name="chart">
+<area shape=rect coords="548,215,628,135" href="file:1083.html" target="_new">
+<area shape=rect coords="298,245,378,205" href="file:1303.html" target="_new">
+<area shape=rect coords="348,345,428,305" href="file:2813.html" target="_new">
+<area shape=rect coords="498,345,578,305" href="file:2023.html" target="_new">
+<area shape=rect coords="698,345,778,305" href="file:2513.html" target="_new">
+<area shape=rect coords="178,375,198,355" href="file:1083.html" target="_new">
+<area shape=rect coords="148,445,228,405" href="file:2333.html" target="_new">
+<area shape=rect coords="498,445,578,405" href="file:2013.html" target="_new">
+<area shape=rect coords="598,445,678,405" href="file:2685.html" target="_new">
+<area shape=rect coords="288,475,308,455" href="file:2013.html" target="_new">
+<area shape=rect coords="198,545,278,505" href="file:3323.html" target="_new">
+<area shape=rect coords="298,545,378,505" href="file:3813.html" target="_new">
+<area shape=rect coords="398,545,478,505" href="file:3413.html" target="_new">
+<area shape=rect coords="498,545,578,505" href="file:3013.html" target="_new">
+<area shape=rect coords="628,545,708,505" href="file:3513.html" target="_new">
+<area shape=rect coords="748,545,828,505" href="file:3503.html" target="_new">
+</map>
+</body></html>
diff --git a/Master/texmf-dist/doc/latex/prerex/chart.pdf b/Master/texmf-dist/doc/latex/prerex/chart.pdf
new file mode 100644
index 00000000000..923c96df131
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/chart.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/prerex/chart.png b/Master/texmf-dist/doc/latex/prerex/chart.png
new file mode 100644
index 00000000000..ba748cd1d6f
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/chart.png
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/prerex/chart.tex b/Master/texmf-dist/doc/latex/prerex/chart.tex
new file mode 100644
index 00000000000..f4a5d526b11
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/chart.tex
@@ -0,0 +1,70 @@
+\documentclass{article}
+\usepackage{geometry}
+\geometry{noheadfoot, vmargin=1.0in, hmargin=0.5in}
+\usepackage{prerex}
+
+\renewcommand{\sfdefault}{phv}
+\usepackage{courier}
+%\renewcommand{\sfdefault}{uop} % uncomment to use URW Optima font
+\renewcommand{\rmdefault}{\sfdefault}
+
+
+\begin{document}
+\thispagestyle{empty}
+\setcounter{diagheight}{50}
+
+
+\begin{chart}\sl
+\text 10,50:{\textbf{\Large Computer}}
+\text 10,47:{\textbf{\Large Science}}
+\reqfullcourse 50,45:{1083}{Comput.\,Sci.\\Concepts}{TTh 10:00}
+\reqhalfcourse 25,40:{1303}{Discrete\\Structures}{MWF 9:30}
+\reqhalfcourse 30,30:{2813}{Computer\\Organiz.\,I}{MWF 8:30}
+ \prereq 50,45,30,30:
+ \prereq 25,40,30,30:
+\reqhalfcourse 45,30:{2023}{Procedural\\Prog.\,Devel.}{MWF 2:30}
+ \prereq 50,45,45,30:
+\reqhalfcourse 65,30:{2513}{Informat.\\Systems}{TTh 1:00}
+ \coreq 50,45,65,30:
+\mini 10,26:{1083}
+\reqhalfcourse 10,20:{2333}{Computab.\,\&\\Formal\,Lang.}{TTh 11:30}
+ \prereq 25,40,10,20:
+ \prereq 10,26,10,20:
+\reqhalfcourse 45,20:{2013}{Software\\Engineer.\,I}{MWF 11:30}
+ \prereq 45,30,45,20:
+\halfcourse 55,20:{2685}{\texttt{C++}\\Program.}{no}
+ \prereq 45,30,55,20:
+\mini 21,16:{2013}
+\reqhalfcourse 15,10:{3323}{Data\\Structures}{MWF 10:30}
+ \prereq 25,40,15,10:
+ \prereq 21,16,15,10:
+\reqhalfcourse 25,10:{3813}{Comput.\\Organiz.\,II}{TTh 8:30}
+ \prereq 30,30,25,10:
+\reqhalfcourse 35,10:{3413}{Operating\\Systems\,I}{MWF 9:30}
+ \prereq 30,30,35,10:
+ \recomm 45,20,35,10:
+\halfcourse 45,10:{3013}{Software\\Engineer.\,II}{MWF 11:30}
+ \prereq 45,20,45,10:
+\halfcourse 58,10:{3513}{Database\\Mngt.\,Sys.\,I}{MWF 8:30 pm}
+ \prereq 65,30,58,10:
+ \prereq 45,20,58,10:
+\reqhalfcourse 70,10:{3503}{Sys.\,Anal.\\\&\,Design}{TTh 10:00}
+ \prereq 65,30,70,10:
+\end{chart}
+
+\begin{center}
+\begin{minipage}{6.0in}
+\begin{itemize}
+\item
+A solid arrow \solidarrow\ indicates a required prerequisite,
+a dotted arrow \dottedarrow\
+indicates a corequisite (to be taken before or concurrently), and a
+dashed arrow \dashedarrow\ indicates a recommended prerequisite.
+Core courses are in \boldbox\ boxes;
+other courses (i.e.,~options or prerequisites)
+are in \lightbox\ boxes.
+\item Timetabling abbreviations: M, T, W, Th, F=Mon, Tue, Wed, Thur, Fri, resp.; eve=7:00--9:50 pm; no=not offered.
+\end{itemize}
+\end{minipage}
+\end{center}
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/prerex/doc/intro.pdf b/Master/texmf-dist/doc/latex/prerex/doc/intro.pdf
new file mode 100644
index 00000000000..7a64fc06d44
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/doc/intro.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/prerex/doc/intro.tex b/Master/texmf-dist/doc/latex/prerex/doc/intro.tex
new file mode 100644
index 00000000000..418b4b0b6cc
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/doc/intro.tex
@@ -0,0 +1,944 @@
+\documentclass[11pt]{article}
+\usepackage[textwidth=6.5in,textheight=8.5in]{geometry}
+
+\usepackage{prerex}
+
+\renewcommand{\textfraction}{0.0}
+\renewcommand{\topfraction}{1.00}
+\renewcommand{\bottomfraction}{1.00}
+
+\usepackage[osf]{mathpazo}
+\usepackage[scaled=0.8]{helvet} % Helvetica scaled down 20%
+
+% \renewcommand{\sfdefault}{uop} % URW clone of Optima
+
+\renewcommand{\ttdefault}{cmtt}
+
+\definecolor{light}{gray}{0.5}
+\definecolor{bg}{rgb}{0.99,0.96,0.90}
+
+\usepackage{graphicx}
+
+\def\LaTeX{\mbox{LaTeX}}
+\def\TeX{TeX}
+\def\MikTeX{\mbox{MikTeX}}
+
+
+\newcommand{\myurl}[1]{\textcolor{blue}{\underline{\textcolor{black}{\url{#1}}}}}
+
+\title{Prerex-Formatted Prerequisite Charts\\[1ex]\Large An Introduction\\[0.5ex]\large \texttt{prerex} Version~6.0}
+\date{}
+\author{Bob Tennent\\School of Computing, Queen's University\\\texttt{rdt@cs.queensu.ca}}
+
+\begin{document}
+\sloppy
+\maketitle
+\thispagestyle{empty}
+
+\tableofcontents
+
+
+\section{Introduction}
+This document is intended to help a user who might want to create or edit prerex-formatted
+prerequisite charts, but is finding the installation and usage instructions in the \textsc{readme}
+and manual pages to be incomprehensible.
+
+\section{Frequently Asked Questions}
+
+
+\subsection*{What is a prerequisite chart?}
+
+A prerequisite chart gives an attractive graphical presentation of courses in a
+program (or set of related programs), organized by terms or years, linked
+by pre- and co-requisite arrows, and, when possible, supplemented by
+timetable information; Figure~\ref{chart}
+%on page~\pageref{chart}
+is a small example.
+
+\input{introchart1}
+
+\subsection*{Who would use a prerequisite chart?}
+
+Prerequisite charts are useful to students selecting courses and planning their
+programs, and to faculty and staff advising students and managing
+curriculum development.
+
+\subsection*{The information is in calendars and on-line; why is a prerequisite chart needed?}
+
+Conventional sources of course, program and timetable information are
+rarely in a user-friendly format. Faculty and staff advisors, being already
+fairly familiar with their courses and programs, often do not appreciate
+how inconvenient it is for students to access all the information they need
+to make course choices.
+
+For example, program requirements are typically specified as lists of
+course codes for required and optional courses; one must look elsewhere to
+find the titles of the courses, the relations between them, their
+prerequisites, and the timetabling information.
+
+As another example, a course description in a calendar typically specifies
+what the prerequisite courses are, but hardly ever specifies which course
+or courses the course is prerequisite to. This information may be very
+important to a student, but to discover it, he or she must search through
+all the subsequent course descriptions in the calendar. With a prerequisite
+chart, it is evident at a glance.
+
+As a third example, consider a student who wants to know whether they can
+defer a course till the following year without risk of timetable conflicts.
+With conventional sources of information, such a question can be answered
+only by doing an exhaustive search through both timetable and calendar for
+a possible conflict. A prerequisite chart incorporating timetable data provides
+the necessary information in a compact and usable form, and the question
+can be answered immediately.
+
+
+\subsection*{If prerequisite charts are so great, why doesn't every university department have them?}
+Few academic departments have the resources to produce prerequisite charts. If
+one searches on the web for "prerequisite chart" or "prerequisite diagram,"
+virtually all of the matches are from departments that one would
+expect to have expertise in technical drawings.
+Here are some of these:
+\begin{itemize}
+\item Queen's University, Electrical and Computer Engineering\footnote{%
+\myurl{http://www.ece.queensu.ca/undergraduate/coursesummaries/Queens_ECE_prerequisite_graph_2007.pdf}}
+\item University of Minnesota, Computer Science\footnote{%
+\myurl{http://www.cs.umn.edu/academics/courses/prereq.php}}
+\item University of Auckland Business School, Department of Information Systems\footnote{%
+\myurl{http://www.code.auckland.ac.nz/comwebcontent/isom/diagrams/ispre-req.html}}
+\item University of Waterloo, Computer Science\footnote{%
+\myurl{http://www.cs.uwaterloo.ca/current/courses/charts/majorPrereq.shtml}}
+\item Georgia Tech, Electrical Engineering\footnote{%
+\myurl{http://www.ece.gatech.edu/academics/undergrad/ee_prereq.html}}
+\item Georgia State University, Computer Science\footnote{%
+\myurl{http://www.cs.gsu.edu/degrees/undergrad/prereq.pdf}}
+\item Langara College, Computer Science and Information Systems\footnote{%
+\myurl{http://www.langara.bc.ca/science-technology/computing-science-systems/course-prerequisites.html}}
+\item Iowa State University, Civil, Construction, \& Environmental Engineering\footnote{%
+\myurl{http://www.ccee.iastate.edu/fileadmin/www.ccee.iastate.edu/academics/mechanical-prereq-0507.pdf}}
+\item Kansas State University, Mathematics\footnote{%
+\myurl{http://www.math.ksu.edu/main/course_info/courses/prereqcht.htm}}
+\item Carleton University, Engineering Physics\footnote{%
+\myurl{http://www.eng.carleton.ca/academicsupport/prereq/EngineeringPhysics.pdf}}
+\item Mississippi State, Civil Engineering\footnote{%
+\myurl{http://www.cee.msstate.edu/documents/flow\%20chart.pdf}}
+\end{itemize}
+
+\pagebreak
+\subsection*{Where can I see prerex-formatted charts in use?}
+
+There are several charts for both specialized and multi-disciplinary programs
+on-line here: \myurl{http://www.cs.queensu.ca/undergraduate/prereq.html}.
+
+\subsection*{What file formats are used for prerex-formatted charts?}
+
+The charts themselves are best distributed in the Portable Document
+Format (PDF) defined by Adobe; PDFs are readable on any platform and in
+most browsers using freely-available software (such as the Adobe Reader),
+printable on any high-resolution printer, relatively compact, and scalable
+to accommodate paper size, display resolution, or user preference.
+
+Charts can also be converted to Portable Network Graphics (PNG)
+format for in-line use on a web page. PNG format is also relatively compact
+and can be rendered directly by most web browsers.
+
+Prerex-formatted charts are produced by software that processes simple and convenient
+text-based descriptions. These descriptions can be edited in any
+text editor or in the \texttt{prerex} interactive editor discussed in Section~\ref{editor}.
+The format of chart descriptions is documented
+in Section~\ref{source}.
+
+
+\subsection*{What software is needed to produce prerex-formatted prerequisite charts?}
+
+To process the description of a prerex-formatted chart, the following software is
+essential:
+\begin{itemize}
+\item an up-to-date standard-conforming implementation of \LaTeX, a powerful
+document processing system based on \TeX, a professional-quality typesetting
+engine; see Section~\ref{installing}.
+\item a few additional \LaTeX\ packages, such as \texttt{pgf}, that may not be included in a minimal \LaTeX\ installation; see Section~\ref{additional};
+\item a file \texttt{prerex.sty} of specialized \LaTeX\ definitions,
+which is included in the prerex package
+available at any repository
+of
+the Comprehensive TeX Archive Network (CTAN)\footnote{%
+\myurl{http://www.ctan.org/}}.
+\end{itemize}
+The following additional software is optional but recommended:
+\begin{itemize}
+\item a PDF viewer that
+\begin{itemize}
+\item can be configured to ``watch'' the PDF file so that it re-loads
+automatically when this is updated, and
+\item shows hyperlinks
+in a ``tooltip'' when the mouse hovers over it, which is a convenient way to get
+the coordinates of course boxes and arrows while editing the description;
+\end{itemize}
+see Section~\ref{PDF}.
+\item suitable fonts; see Section~\ref{fonts}.
+\item the \texttt{prerex} interactive editor for prerex-formatted charts;
+see Section~\ref{editor}.
+\item an integrated \LaTeX\ development environment; see Section~\ref{IDE}.
+\end{itemize}
+
+\subsection*{Why couldn't I use a program like Visio\textsuperscript{\textregistered}\ or CorelDRAW\textsuperscript{\textregistered}\ to produce a prerequisite chart?}
+You could, if you have such a program available, are very skilled in its
+use, and won't be embarrassed
+distributing a chart that looks amateurish. Look carefully at a prerex-formatted
+chart and notice the following properties:
+\begin{itemize}
+\item Each course box is sized to just enclose the text within it, with
+ uniform standard margins.
+\item Each arrow between courses is oriented from box centre to box centre,
+ rather than from/to standard "connection points" on the box edges.
+\item The arrows are "clipped" by the course boxes, but the arrow heads abut
+ the target box exactly.
+\end{itemize}
+These desirable properties are not easily achieved using conventional
+``do-it-yourself'' drawing software, no matter how ``user-friendly'' it
+purports to be.
+The prerex system provides complete flexibility as well as professional
+quality:
+\begin{itemize}
+\item Text within a course box may be partitioned into regions with varying
+ characteristics. For example, the course code and the timetable
+ information on the first line of course boxes are in a smaller font
+ than the course name. The latter is centered and the former are left-
+ and right-justified, respectively. Arbitrary \LaTeX\ formatting can be used
+ for the text.
+\item Any available Type 1 (Postscript) or TrueType format fonts may be used;
+ in the chart in Figure~\ref{chart}, the typeface used is Optima, an elegant
+ \emph{sans serif} face designed by Hermann Zapf. The professional-quality
+ typesetting engine takes advantage of kerns and ligatures in the fonts.
+\item Line thickness for boxes may be varied; in the example diagram, heavier
+ boxes (and bold-face text) are used to indicate that a course is
+ "required" in the program, rather than an option.
+\item Different styles of connectors can be used, for example to distinguish
+ prerequisites, co-requisites, and recommended prerequisites.
+\item Various sizes or shapes of course boxes may be used, for example to
+ distinguish between half and full courses.
+\item Graphic images such as logos can be imported.
+\item Colours and hyperlinks to on-line course descriptions or calendars are
+ possible.
+\end{itemize}
+\subsection*{Wouldn't a commercial drafting service be able to produce a professional-looking prerequisite chart?}
+
+Possibly, but you will almost certainly have to do the global lay-out
+yourself. A more serious long-term problem is that it is unlikely you will
+be able to maintain the chart yourself using freely available software. You
+will be "locked-in" to use the drafting service for every future
+modification of the chart.
+
+If you want the quality and maintainability of a prerex-formatted chart but
+don't think you can produce it yourself, you can outsource the production;
+check out the following:
+\myurl{http://www.prerex.com}.
+
+\subsection*{How can a prerex-formatted chart be edited?}
+University programs and timetables
+change frequently: courses are added or dropped,
+pre- or co-requisites or timetabling of courses change, and so on.
+Use of a separate text-based description file and intelligent processing
+software make it easy to modify a prerex-formatted chart. If the text within a course
+box is changed, the size of the box, the length of connectors to and from
+that box, and the location of arrowheads into the box are all adjusted
+automatically by the processing software. If a course box must be moved, it
+is straightforward to edit the relevant instructions for arrows into or
+from the box because the coordinates specified for an arrow are those of
+the box centres, rather than those of the edges or corners of the boxes.
+Small changes can be made with any text editor.
+
+For creating a prerex-formatted chart or for
+making substantial changes to an existing chart, the \texttt{prerex} interactive chart editor is available;
+see Section~\ref{editor}.
+
+Editing a text file in either of these ways is far easier and
+faster than trying to fiddle with an image using a mouse.
+
+
+\section{Viewing and Printing a Prerequisite Chart}
+\label{PDF}
+
+A prerequisite chart in Portable Document Format (PDF) can be ``opened'' for
+viewing or printing in any PDF viewer. The most
+popular of these is the
+Adobe Reader.\footnote{\myurl{http://www.adobe.com/prodindex/acrobat/readstep2.html}}
+However, the Adobe Reader is quite slow to load and somewhat inconvenient to use
+if one wants to re-load the document after changing it (one must first close the document and
+then re-open it).
+
+There are faster and more convenient alternatives to the Adobe Reader. One
+that is
+available for Windows, Macs, and Linux systems is a
+ghostscript-based viewer called
+GSview.\footnote{%
+\myurl{http://www.cs.wisc.edu/~ghost/}}
+For Windows or Linux: download and install the most recent version of
+ghostscript for your platform,\footnote{%
+\myurl{http://www.cs.wisc.edu/~ghost/doc/AFPL/index.htm}}
+and then install the most recent version of
+GSview for your platform.\footnote{%
+\myurl{http://www.cs.wisc.edu/~ghost/gsview/index.htm}}
+For Macs: just get
+MacGSView.\footnote{%
+\myurl{http://www.cs.wisc.edu/~ghost/macos/index.htm}}
+
+For Linux systems, other ghostscript-based viewers such as
+\texttt{gv}\footnote{%
+\myurl{http://wino.physik.uni-mainz.de/~plass/gv/}}
+are available. Also,
+\texttt{xpdf}\footnote{%
+\myurl{http://www.foolabs.com/xpdf/home.html}}
+is suitable for any X-window based systems, such as any version of Linux.
+If Gnome or KDE libraries are installed, variants \texttt{gpdf}, \texttt{kghostview}, \texttt{evince}, and \texttt{kpdf} (now renamed \texttt{okular}) of these programs are available.
+You may print a prerequisite chart from within any of these viewing applications.
+
+If you are \emph{editing} a prerequisite chart (using either a text editor on the
+chart description or
+the \texttt{prerex} editor), you will want to use a PDF viewer that
+not only can be configured to ``watch'' the PDF file (so that it re-loads
+automatically when this is updated), but also
+shows hyperlinks
+in a ``tooltip'' when the mouse hovers over it; this is a convenient way to get
+the coordinates of course boxes and arrows while editing the description.
+Recent versions of some of these viewing programs have the latter capability.
+
+\texttt{kpdf} (a.k.a.~\texttt{okular}) is an open-source PDF viewer for KDE\@. The prerex distribution
+(from version 3.2) contains a ``patch'' file that can be used to modify
+the source files for \texttt{kpdf}/\texttt{okular} so it can display URI tooltips and
+capture box, connector, or background-point coordinates while the coordinate grid is
+enabled.
+See the README for instructions on obtaining the sources, patching them,
+and building and installing a prerex-enabled version of \texttt{kpdf}/\texttt{okular}.
+
+\section{Installing a Basic \LaTeX\ System}
+\label{installing}
+
+To ``process'' a chart description, you will need to install an application
+called \LaTeX, together with several auxiliary applications to convert the
+output into Postscript and then PDF.
+
+
+\LaTeX\ is a powerful document processor based on a professional-quality typesetting program called \TeX. The following web sites
+will point you to as much information as you might want on \LaTeX\ and \TeX:
+\begin{itemize}
+\item \LaTeX\ Project home page\footnote{\myurl{http://www.latex-project.org}}
+\item \TeX\ Users Group home page\footnote{\myurl{http://www.tug.org/}}
+\item \TeX\ FAQ\footnote{\myurl{http://www.tex.ac.uk/cgi-bin/texfaq2html}}
+\end{itemize}
+
+If you use Windows,
+we suggest you install the ``basic'' version of
+MiKTeX.\footnote{%
+\myurl{http://www.miktex.org/setup.html}}
+If you use Mac~OS~X, go to
+the \emph{\TeX\ on Mac OS~X} site.\footnote{%
+\myurl{http://www.rna.nl/tex.html}}
+Unix and Linux users should install \texttt{tetex} packages, or
+get the sources from
+the \emph{teTeX Homepage}.\footnote{%
+\myurl{http://www.tug.org/teTeX/}}
+
+The resulting installation will allow you to process simple \texttt{.tex} files.
+However, you won't be able
+to process the description of a prerex-formatted prerequisite chart until some necessary additional software is installed.
+
+\section{Additional \LaTeX\ Software}
+\label{additional}
+
+To process descriptions of prerex-formatted charts, some additional packages
+are needed.
+The file \texttt{prerex.sty} is essential;
+it should be stored
+in the same folder as the \texttt{.tex} file to be processed
+(or in the
+local \verb|texmf| tree) so the \LaTeX\ system can find it.
+Other add-ons that may be necessary are as follows:
+\texttt{pgf},
+\texttt{tikz},
+\texttt{multido},
+\texttt{textcomp}, and
+\texttt{xcolor}.
+If you are using \MikTeX, these can be installed using the
+package manager, or, if you prefer,
+will be installed automatically the first time a chart description is processed.
+If you are not using \MikTeX, all of the packages are available
+for download from any CTAN\footnote{%
+\myurl{http://www.ctan.org/}} repository.
+
+You are now ready to process the description for a chart.
+Get a command-line
+prompt, move to the folder with the chart description and issue the following
+instruction:
+\begin{verbatim}
+ pdflatex chart
+\end{verbatim}
+This operation will overwrite
+any existing \verb|chart.pdf|, so you should first re-name
+that file if you want to preserve it.
+
+If the \texttt{pdflatex} command isn't recognized, you
+will have to
+edit the
+system executable-command path.
+On a Unix-like system, adjust the value of \texttt{PATH}; on
+Windows, click on \emph{Control~Panel} $\rightarrow$ \emph{System} $\rightarrow$ \emph{Advanced} $\rightarrow$ \emph{Environment~Variables},
+select \emph{Path} and click on \emph{Edit}; then append the appropriate
+paths,
+separated by semi-colons. For \MikTeX, the default path for commands is
+\verb|C:\texmf\miktex\bin|.
+
+
+
+\section{Installing a \LaTeX\ Development Environment}
+\label{IDE}
+Most beginning
+users will prefer
+to use a graphical ``development environment'' which supports editing, processing and
+previewing of documents, rather than the command-line interface. There are \emph{many} such applications.
+
+For Windows, we suggest you go
+the Texmaker download site\footnote{%
+\myurl{http://www.xm1math.net/texmaker/download.html}}
+and click on the link for the self-installing archive
+\verb|texmakerwin32_install.exe|.
+For Mac OS~X, go to the same site, get
+the \texttt{texmakerbinmacosx} archive and follow the instructions.
+For Linux, install a \texttt{texmaker} package or get the source files
+at the Texmaker site.
+
+When Texmaker has been installed,
+start it up and
+then click on \emph{Options} $\rightarrow$ \emph{Configure~Texmaker} to
+do any necessary configuration, such as the \emph{Quick Build} operation.
+
+You should now be able to
+open the source file for your chart,
+process
+it, and then view the result
+using the items in the \emph{Tools} menu, or the \emph{Quick~Build} button.
+If there are any processing errors, error messages will appear in the bottom window pane.
+
+Many other LaTeX editors are available if
+Texmaker doesn't satisfy you. Two of the most popular of
+these for Windows are
+WinEdt\footnote{%
+\myurl{http://www.winedt.com/}}
+and
+TeXnicCenter;\footnote{%
+\myurl{http://sourceforge.net/projects/texniccenter}}
+the former is ``shareware'' and the latter is free.
+Mac users may want to check out the list of ``front-ends''
+at the \emph{TeX on Mac OS~X} site.\footnote{%
+\myurl{http://www.rna.nl/tex.html}}.
+Linux users also have
+Kile\footnote{%
+\myurl{http://kile.sourceforge.net/}}
+and
+Klat.\footnote{%
+\myurl{http://research.edm.luc.ac.be/jori/klat/klat.html}}
+\newpage
+
+\section{Fonts}
+\label{fonts}
+
+Look carefully at the samples in Figure~\ref{samples}.
+\begin{figure}
+\centering
+\includegraphics*[scale=0.35]{introFonts}
+\caption{Typeface Samples}
+\label{samples}
+\end{figure}
+Times and Palatino are \emph{serifed} typefaces; the serifs are the small projections
+at the baselines, and sometimes at the tops, of characters.
+Serifs improve the readability of \emph{long} texts.
+The others
+are \emph{sans serif} typefaces; this class of typefaces is more
+appropriate for use in prerequisite charts where \emph{legibility} of fairly small and short textual fragments is of primary importance.
+
+To specify that the default text font in a \LaTeX\ document is to be \emph{sans serif},
+the following command is used in the preamble of the source file:
+\begin{verbatim}
+ \renewcommand{\rmdefault}{\sfdefault}
+\end{verbatim}
+
+Computer Modern Sans is the default \emph{sans serif} font in \LaTeX,
+and Helvetica and Avant~Garde should also be available in every \LaTeX\ installation.
+But we recommend that you consider Optima.
+If you look
+carefully at the samples above, you'll see that, unlike the boringly uniform strokes of
+the Computer Modern,
+Helvetica, Avant~Garde, Futura, and Gill Sans characters, the strokes of the Optima characters are
+\emph{tapered} (i.e.,~shaped). This gives Optima text an elegance and liveliness
+lacking in most other \emph{sans serif} typefaces.
+Palatino (used in this document) and Optima were both designed by
+Hermann Zapf, considered the foremost type designer of the modern era.
+
+So how does one install Optima (or any other non-standard typeface)
+for use with \LaTeX? Authentic Optima fonts in Windows Postscript (Adobe Type~1)
+format are available
+commercially from font vendors such as \texttt{myfonts.com}.
+The necessary \LaTeX\ support files and instructions for installation
+into a standard \LaTeX\ implementation may be found
+at CTAN\footnote{%
+\myurl{http://www.ctan.org/tex-archive/fonts/psfonts/w-a-schmidt/}};
+the file \texttt{pop.zip} is the package of support files and \texttt{pop.txt}
+gives the installation instructions.
+
+But there are less expensive alternatives.
+The name ``Optima'' is trademarked by Linotype, but
+other font foundries have
+produced good-quality clones with other names.
+For example, the family of Zapf-Humanist~601 fonts from \mbox{Bitstream}
+are available from commercial distributors such as \texttt{myfonts.com}. They are actually more expensive than authentic Optima; however, some of these fonts have been bundled with
+Corel applications such as \mbox{WordPerfect}, and so you may
+already have them. The support files for \LaTeX\ (\texttt{bop.zip}) and instructions (\texttt{bop.txt}) are also available
+at the site referenced above.
+
+Another usable clone of Optima is the URW~Classico family of fonts. Although
+they are only slightly less expensive than authentic Optima at commercial vendors,
+four Classico fonts are available in a package
+of 79~fonts in Type~1 format that may be legally downloaded for non-commercial use
+from
+Artifex\footnote{%
+\myurl{http://www.artifex.com/downloads/}}.
+The four Classico font files, renamed for use in \LaTeX, with the necessary support files and installation instructions are available
+from CTAN\footnote{%
+\myurl{ftp://tug.ctan.org/pub/tex-archive/nonfree/fonts/urw/classico.zip}}.
+Note that the font files cannot be distributed commercially without a commercial license; please read the license in the archive
+before re-distributing them.
+
+When any of these Optima or Optima-like fonts and corresponding
+support files have been installed,
+it will be possible to request their use in your charts by
+using \texttt{pop}, \texttt{bop}, or \texttt{uop} in a
+\begin{verbatim}
+ \renewcommand{\sfdefault}{...}
+\end{verbatim}
+command in the preamble of the source file.
+To get Helvetica (scaled down 20\%) or Avant Garde, use
+\begin{verbatim}
+ \usepackage[scaled=0.8]{helvet}
+\end{verbatim}
+or
+\begin{verbatim}
+ \renewcommand{\sfdefault}{pag}
+\end{verbatim}
+respectively.
+If none of these is used,
+(or the command is commented out by preceding
+it with a \verb|%| character), Computer Modern Sans will be used.
+
+\section{Conversion to Portable Network Graphic (PNG) Format}
+
+Although PDF is currently the best available format for distributing
+and printing charts, you may want to produce a raster-image version for
+use on a web site. There are several conversion programs and services
+available to do this. For example, the \verb|convert| tool of the
+multi-platform \verb|ImageMagick|\footnote{%
+\myurl{http://www.imagemagick.org/}}
+package may be used as follows:
+\begin{verbatim}
+ convert -density 125 -quality 100 chart.pdf chart.png
+\end{verbatim}
+The density parameter specifies the number of pixels per inch; if this is too small, the
+image is of poor quality, and if it is too large, the image file is too big.
+The quality parameter ensures maximal (loss-free) compression.
+From version 5.0, \verb|prerex.sty| generates an auxiliary file
+containing image-map data for the hyperlinked nodes in the chart; consult a
+reference on the HTML language for an explanation of (client-side) image maps.
+
+
+\section{Terminology and Coordinate System}
+Before we discuss the \texttt{prerex} editor and the format
+of ``source files'' (i.e.,~chart descriptions), we shall summarize the necessary terminology and coordinate
+conventions.
+
+A prerequisite chart consists of a number of
+\emph{course boxes},
+linked by
+\emph{arrows}.
+Courses are either
+\emph{half}
+or
+\emph{full},
+and may be
+\emph{required}.
+Each course box can contain a course
+\emph{code}
+(upper left corner),
+a course
+\emph{title}
+(lower half),
+and
+\emph{timetable}
+information
+(upper right corner).
+An arrow can be either a \emph{prerequisite} (solid),
+a \emph{co-requisite} (dotted),
+or
+\emph{recommended} (dashed).
+When a conventional arrow would be inappropriate, it is possible to use
+a
+\emph{mini}
+course ``box'' (consisting of just a course code) just above a target box.
+A line of text may be placed anywhere on the chart.
+
+A conventional two-dimensional
+Cartesian coordinate system is used to specify the locations of
+diagram elements.
+The
+origin (where
+$x = 0$
+and
+$y = 0$)
+is at the lower-left corner of the diagram.
+
+The diagram height is configurable; the width is determined by
+the values of the \LaTeX\ length
+\verb|\textwidth|
+and
+an adjustable
+\verb|\unit|
+length, which defines the absolute value of a coordinate unit.
+It is possible to put a coordinate grid with labelled axes
+in the background of a chart.
+
+The coordinates of a
+\emph{box,}
+\emph{mini,
+or
+\emph{text-line}}
+are those of its centre point.
+An
+\emph{arrow}
+is described by the
+coordinates of the centre points of its source and target boxes/minis/text-lines.
+
+\section{Chart Editing}
+\label{editor}
+The source code of \texttt{prerex}, an interactive (command-line) prerequisite-chart editor, is available at
+CTAN repositories.\footnote{\myurl{http://www.ctan.org/tex-archive/graphics/prerex/}}
+It should build on any \textsc{Unix}-like system with
+suitable tools and libraries installed; for example, it can be compiled
+on GNU/Linux, Solaris, the Cygwin\footnote{\myurl{http://www.cygwin.com/}}
+platform on Windows,
+and the Fink\footnote{\myurl{http://fink.sourceforge.net/}} platform
+on OS~X, if the GNU \texttt{readline} library is installed.
+
+The editor supports add, remove, cut-and-paste, and edit operations
+on course boxes, minis, text-lines, and arrows, and shifts of specified diagram elements or an entire diagram.
+A summary of all
+commands supported by \texttt{prerex} is given in Table~\ref{help}
+on page~\pageref{help}.
+Note that if a course box/mini/text-line is ``cut''
+and then ``pasted'' elsewhere, the target or source coordinates of arrows into or out of the source and target are
+adjusted accordingly, and similarly if nodes are shifted or raised. To allow permutations of two or more
+chart elements, the
+editor maintains a ``stack'' of elements that have been cut but not yet pasted.
+\begin{table}
+\begin{center}\small
+\begin{tabular}{|l|l|}
+\hline
+ \multicolumn{1}{|c|}{\textbf{Command}} & \multicolumn{1}{|c|}{\textbf{Effect}} \\
+\hline\hline
+
+\verb\file.tex> box x,y \ & [create and] edit course box at $x,y$\\
+\verb\file.tex> mini x,y \ & [create and] edit mini course at $x,y$\\
+\verb\file.tex> text x,y \ & [create and] edit text centered at $x,y$\\
+\verb\file.tex> arrow x0,y0,x1,y1\ & [create and] edit arrow from $x0,y0$ to $x1,y1$\\
+\verb\file.tex> cut x,y \ & (temporarily) remove box, mini, or text at $x,y$\\
+\verb\file.tex> paste x,y \ & re-insert removed box, mini, or text at $x,y$\\
+\verb\file.tex> delete [x,y | x0,y0,x1,y1] ...\ & remove specified elements/arrows\\
+\verb\file.tex> undelete \ & undelete deleted box, mini, text, or arrow\\
+\verb\file.tex> write | ! \ & save to \verb\file.tex\ and process (with \verb\pdflatex)\\\
+\verb\file.tex> quit | exit | x | ^D\& turn off grid, save to \verb\file.tex\, process, and exit\\
+\verb\file.tex> shift [-]x [xi,yi ...]\ & move [specified] elements $x$ units right [left]\\
+\verb\file.tex> raise [-]y [xi,yi ...]\ & move [specified] elements $y$ units up [down]\\
+\verb\file.tex> !cmd \ & execute shell command \verb\cmd\, then reload\\
+\verb\file.tex> Backup \ & copy \verb\file.tex\ to \verb\.file.tex\\\
+\verb\file.tex> Restore \ & restore from \verb\.file.tex\\\
+\verb\file.tex> grid [y/n] \ & turn on/off coordinate grid background\\
+\verb\file.tex> help | ? \ & print this summary\\
+\hline
+\end{tabular}
+\end{center}
+\caption{\texttt{prerex} Command Summary (version 6.0)}
+\label{help}
+\end{table}
+
+The effects of
+editing operations may be observed in a PDF
+viewer. See the manual page \texttt{prerex(1)} for
+more information. The \texttt{prerex} package at CTAN
+also has the source files for
+\texttt{vprerex} (visual \texttt{prerex}), a graphical ``wrapper'' for \texttt{prerex}
+which incorporates a prerex-enabled PDF viewer.
+
+
+For initial creation of a prerex-formatted chart
+or making
+substantial changes to the boxes and arrows of an existing prerex-formatted chart, it is more convenient
+to use one of these programs than to edit the source file directly; however,
+the chart editor has no access to other elements of a source file, such as
+preamble declarations, headings, notes, logos, and so on. A conventional text editor or
+\LaTeX\ development environment should be used for these.
+
+\section{Source Files}
+\label{source}
+
+\subsection{Overall Structure}
+
+A \texttt{.tex} file is essentially text with interspersed
+\LaTeX\ commands, much as a web-page description has text with Hypertext
+Mark-up Language (HTML) tags interspersed.
+Commands for \LaTeX\ can be recognized by the initial backslash character~``\verb|\|''.
+
+The first several lines make up the ``preamble''
+of the source file for a chart:
+\begin{verbatim}
+ \documentclass{article}
+ \usepackage{prerex}
+ :
+\end{verbatim}
+This describes the kind of document to be processed (\texttt{article}, as opposed to
+\texttt{book} or \texttt{report}) and
+indicates a file of definitions to be used (\texttt{prerex.sty}).
+The remaining lines of the preamble
+specify such things as the page layout and the fonts to be used.
+
+The structure
+\begin{verbatim}
+ \begin{document}
+ :
+ \end{document}
+\end{verbatim}
+contains the content of the document.
+Typically, the first element of the content is a heading, contained
+within a
+formatting structure of the form
+\begin{verbatim}
+ \begin{center}
+ :
+ \end{center}
+\end{verbatim}
+which specifies that each line of the material contained should be centered on the page.
+The double-backslash command \verb|\\| indicates
+a line break.
+
+After the heading comes the description of the chart itself:
+\begin{verbatim}
+ \begin{chart}
+ :
+ \end{chart}
+\end{verbatim}
+Finally, there
+will typically be some notes to explain the abbreviations and conventions
+used in the chart.
+
+\subsection{Chart Instructions}
+
+
+Table~\ref{instructions}
+on page~\pageref{instructions}
+summarizes the formats of
+the instructions defined by \texttt{prerex.sty}.
+\begin{table}
+\begin{center}
+\renewcommand{\arraystretch}{1.3333}
+\begin{tabular}{|l|}
+\hline
+\multicolumn{1}{|c|}{\textbf{Course Boxes and Text-Lines}} \\
+\hline
+\verb|\halfcourse |$x,y$:\verb|{|\emph{course code}\verb|}{|\emph{course title}\verb|}{|\emph{timetable code}\verb|}| \\
+\verb|\fullcourse |$x,y$:\verb|{|\emph{course code}\verb|}{|\emph{course title}\verb|}{|\emph{timetable code}\verb|}| \\
+\verb|\reqhalfcourse |$x,y$:\verb|{|\emph{course code}\verb|}{|\emph{course title}\verb|}{|\emph{timetable code}\verb|}| \\
+\verb|\reqfullcourse |$x,y$:\verb|{|\emph{course code}\verb|}{|\emph{course title}\verb|}{|\emph{timetable code}\verb|}| \\
+\verb|\mini |$x,y:$\verb|{|\emph{course code}\verb|}| \\
+\verb|\text |$x,y:$\verb|{|\emph{line of text}\verb|}| \\
+\hline
+\multicolumn{1}{|c|}{\textbf{Arrows}} \\
+\hline
+\verb|\prereq |$x_0, y_0, x_1, y_1$: \hfil
+\verb|\prereqc |$x_0, y_0, x_1, y_1$; \emph{c}: \\
+\verb|\coreq |$x_0, y_0, x_1, y_1$: \hfil
+\verb|\coreqc |$x_0, y_0, x_1, y_1$; \emph{c}: \\
+\verb|\recomm |$x_0, y_0, x_1, y_1$: \hfil
+\verb|\recommc |$x_0, y_0, x_1, y_1$; \emph{c}: \\
+\hline
+\multicolumn{1}{|c|}{\textbf{Coordinate Grid}} \\
+\hline
+\verb|\grid| \\
+\hline
+\multicolumn{1}{|c|}{\textbf{In-Line Instructions}} \\
+\hline
+\verb|\solidarrow| \\
+\verb|\dottedarrow| \\
+\verb|\dashedarrow| \\
+\verb|\lightbox| \\
+\verb|\boldbox| \\
+\hline
+\end{tabular}
+\renewcommand{\arraystretch}{1.0}
+\end{center}
+\caption{Instructions for \texttt{prerex}-Formatted Prerequisite Charts}
+\label{instructions}
+\end{table}
+
+The \verb\grid\ command creates
+a light gray ``coordinate grid'' in the background of the chart.
+Figure~\ref{grid}
+on page~\pageref{grid}
+shows the example chart of Figure~\ref{chart} with the coordinate
+grid enabled.
+\input{introchart2}
+Note that the ``origin'' of the coordinate system (the point
+with $x$-coordinate $0$ and $y$-coordinate $0$) is at the lower-left corner of the chart.
+
+The arrows produced by \verb\prereq\, \verb\coreq\, and \verb\recomm\ instructions
+by default are slightly curved (except very short ones). It is possible to increase
+or decrease the degree of curvature of a particular arrow by using instructions
+\verb\prereqc\, \verb\coreqc\, or \verb\recommc\; the additional argument
+specifies the degree of curvature: $0$ means no curvature, i.e.,~straight,
+and to increase the curvature, use a larger number (up to $100$).
+To change the default curvature for \emph{all} arrows,
+see Section~\ref{config} on page~\pageref{config} below.
+
+
+The ``in-line'' instructions create small examples of course boxes and arrows for use
+in explanatory notes outside of the \verb\chart\ environment:
+\begin{list}{}{}\item
+\renewcommand{\arraystretch}{1.25}
+\begin{tabular}{lc}
+\verb|\solidarrow| & \solidarrow \\
+\verb|\dottedarrow| & \dottedarrow \\
+\verb|\dashedarrow| & \dashedarrow \\
+\verb|\lightbox| & \lightbox \\
+\verb|\boldbox| & \boldbox
+\end{tabular}
+\renewcommand{\arraystretch}{1.0}
+\end{list}
+
+
+See the manual pages
+\texttt{prerex(5)} and \texttt{prerex.sty(7)} and the documentation for
+\texttt{prerex.sty} for more information.
+
+\subsection{\LaTeX\ Input Conventions}
+
+The following are some of the input conventions for \LaTeX\ that you might want to know
+about while editing
+the source file for a prerex-formatted prerequisite chart.
+\begin{itemize}
+\item The characters \verb|# $ % & _ { } ~ ^ \ | are interpreted in special
+ways by \LaTeX; to produce any of the first seven of these characters, you will have
+to ``escape'' them with a backslash, as in, for example, \verb|\&|.
+The \verb|\\| combination produces a line break; to produce a backslash, use \verb|\backslash|. The remaining two special characters, \verb|~|
+and \verb|^|, may also be escaped with a backslash but produce accents;
+for example, \verb|\^{u}| produces~\^{u}.
+
+\item To produce a space where \LaTeX\ would normally not do so, use \verb|\ |.
+For example, \LaTeX\ normally interprets a period immediately after a word as the end of
+a sentence and leaves a larger-than-usual space; to prevent the larger-than-usual space after an abbreviation
+that finishes with a period, use \verb|\ | instead of a space, as in
+\verb|Diff.\ Equations|.
+
+\item An unescaped \verb\%\ character signals the beginning of a comment; any characters following the
+\verb\%\ to the end of that line are ignored by \LaTeX.
+
+\item To prevent a line break between two words, use a \verb\~\
+instead of a space between them, as in \verb\MATH~223\.
+
+\item To leave a smaller-than-usual space between two words,
+use \verb|\,| instead of a space between them, as in \verb|MATH\,223|.
+
+\item To prevent hyphenation of some word, use the word as the argument to
+an \verb|\mbox| command, as in \verb|\mbox{Robert}|.
+
+
+\end{itemize}
+
+\subsection{Configuration}
+\label{config}
+
+The following \LaTeX\ definitions are made in
+\verb|prerex.sty| but may be re-defined by the
+user in the chart source file:
+\begin{list}{}{}
+\item \verb|\newcommand{\DefaultCurvature}{20}|
+\end{list}
+where the argument should be in the range $0$--$100$; $0$ means no curvature.
+\begin{list}{}{}
+\item \verb|\newcommand{\CourseURL}[3]{#3.html}|
+\end{list}
+where the arguments supplied at the call are the $x$ and $y$ coordinates of
+the box or mini, and the course code.
+\begin{list}{}{}
+\item \verb|\newcommand{\background}{LightYellow}|
+\end{list}
+where
+\verb|LightYellow|
+is defined by
+\begin{list}{}{}
+\item \verb|\definecolor{LightYellow}{rgb}{1.0, 1.0, 0.878431}|
+\end{list}
+\begin{list}{}{}
+\item \verb|\setlength{\unit}{5.7816pt}|
+\end{list}
+which defines the absolute size of a coordinate unit;
+this results in exactly 10 pixels per
+coordinate unit if the chart is converted to an image at 125 dpi.
+\begin{list}{}{}
+\item \verb|\newcommand{\dpi}{125}|
+\item \verb|\newcommand{\PixelsPerUnit}{10}|
+\end{list}
+These three commands have to re-defined together if the image-map data are to be correct.
+\begin{list}{}{}
+\item \verb|\setcounter{diagheight}{75}|
+\end{list}
+which is the
+$y$-coordinate
+of the top of the diagram (reduced to $65$ in landscape mode);
+the nominal diagram width is
+\verb|\textwidth|~$\div$~\verb|\unit|~$+ 10$.
+
+The following define the thicknesses of the three kinds of arrows
+and the thickness of bold boxes:
+\begin{list}{}{}
+\item
+\verb|\newcommand{\solidwidth}{0.5pt}|
+\item
+\verb|\newcommand{\dottedwidth}{0.8pt}|
+\item
+\verb|\newcommand{\dashedwidth}{0.8pt}|
+\item
+\verb|\newcommand{\boldwidth}{1.0pt}|
+\end{list}
+
+
+The following command is used to change to a smaller size for course codes,
+timetable information, and mini-course codes:
+\begin{list}{}{}
+\item
+\verb|\newcommand{\smallersize}{\relsize{-3}}|
+\end{list}
+
+\newpage
+
+
+
+\section*{Bibliography}
+\addcontentsline{toc}{section}{Bibliography}
+\label{bibliography}
+
+The following \nocite{Kopka,Lamport,Mittelbach} are three recommended books on \LaTeX\@.
+Many other books and tutorial materials are available; check out the web sites referenced
+in Section~\ref{installing}.
+\renewcommand{\refname}{}
+\vspace*{-6ex}
+\bibliography{manual}
+\bibliographystyle{plain}
+
+
+
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/prerex/doc/introFonts.png b/Master/texmf-dist/doc/latex/prerex/doc/introFonts.png
new file mode 100644
index 00000000000..5b4e212f4a5
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/doc/introFonts.png
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/prerex/doc/introchart1.tex b/Master/texmf-dist/doc/latex/prerex/doc/introchart1.tex
new file mode 100644
index 00000000000..aad3583ce06
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/doc/introchart1.tex
@@ -0,0 +1,58 @@
+\begin{figure}
+\renewcommand{\rmdefault}{\sfdefault}
+\setcounter{diagheight}{50}
+\textwidth6.25in
+\begin{chart}\sl
+\text 20,50:{\textsf{\textbf{\Large Computer Science}}}
+\reqfullcourse 50,45:{1083}{Comput.\,Sci.\\Concepts}{TTh 10:00}
+\reqhalfcourse 25,40:{1303}{Discrete\\Structures}{MWF 9:30}
+\reqhalfcourse 30,30:{2813}{Computer\\Organiz.\,I}{MWF 8:30}
+ \prereq 25,40,30,30:
+ \prereq 50,45,30,30:
+\reqhalfcourse 45,30:{2023}{Procedural\\Prog.\,Devel.}{MWF 2:30}
+ \prereq 50,45,45,30:
+\reqhalfcourse 65,30:{2513}{Informat.\\Systems}{TTh 1:00}
+ \coreq 50,45,65,30:
+\mini 10,26:{1083}
+\reqhalfcourse 10,20:{2333}{Computab.\,\&\\Formal\,Lang.}{TTh 11:30}
+ \prereq 10,26,10,20:
+ \prereq 25,40,10,20:
+\reqhalfcourse 45,20:{2013}{Software\\Engineer.\,I}{MWF 11:30}
+ \prereq 45,30,45,20:
+\halfcourse 55,20:{2685}{\texttt{C++}\\Program.}{no}
+ \prereq 45,30,55,20:
+\mini 21,16:{2013}
+\reqhalfcourse 15,10:{3323}{Data\\Structures}{MWF 10:30}
+ \prereq 21,16,15,10:
+ \prereq 25,40,15,10:
+\reqhalfcourse 25,10:{3813}{Comput.\\Organiz.\,II}{TTh 8:30}
+ \prereq 30,30,25,10:
+\reqhalfcourse 35,10:{3413}{Operating\\Systems\,I}{MWF 9:30}
+ \recomm 45,20,35,10:
+ \prereq 30,30,35,10:
+\halfcourse 45,10:{3013}{Software\\Engineer.\,II}{MWF 11:30}
+ \prereq 45,20,45,10:
+\halfcourse 58,10:{3513}{Database\\Mngt.\,Sys.\,I}{MWF 8:30 pm}
+ \prereq 45,20,58,10:
+ \prereq 65,30,58,10:
+\reqhalfcourse 70,10:{3503}{Sys.\,Anal.\\\&\,Design}{TTh 10:00}
+ \prereq 65,30,70,10:
+\end{chart}
+\begin{center}
+\begin{minipage}{6.0in}
+\begin{itemize}\sf
+\item
+A solid arrow \solidarrow\ indicates a required prerequisite,
+a dotted arrow \dottedarrow\
+indicates a corequisite (to be taken before or concurrently), and a
+dashed arrow \dashedarrow\ indicates a recommended prerequisite.
+Core courses are in \boldbox\ boxes;
+other courses (i.e.,~options or prerequisites)
+are in \lightbox\ boxes.
+\item Timetabling abbreviations: M, T, W, Th, F=Mon, Tue, Wed, Thur, Fri, resp.; eve=7:00--9:50 pm; no=not offered.
+\end{itemize}
+\end{minipage}
+\end{center}
+\caption{A Prerex-Formatted Prerequisite Chart}
+\label{chart}
+\end{figure}
diff --git a/Master/texmf-dist/doc/latex/prerex/doc/introchart2.tex b/Master/texmf-dist/doc/latex/prerex/doc/introchart2.tex
new file mode 100644
index 00000000000..a7ebd465dd7
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/doc/introchart2.tex
@@ -0,0 +1,45 @@
+\begin{figure}
+\renewcommand{\rmdefault}{\sfdefault}
+\textwidth6.25in
+\setcounter{diagheight}{50}
+\begin{chart}\sl
+\grid
+\text 20,50:{\textsf{\textbf{\Large Computer Science}}}
+\reqfullcourse 50,45:{1083}{Comput.\,Sci.\\Concepts}{TTh 10:00}
+\reqhalfcourse 25,40:{1303}{Discrete\\Structures}{MWF 9:30}
+\reqhalfcourse 30,30:{2813}{Computer\\Organiz.\,I}{MWF 8:30}
+ \prereq 25,40,30,30:
+ \prereq 50,45,30,30:
+\reqhalfcourse 45,30:{2023}{Procedural\\Prog.\,Devel.}{MWF 2:30}
+ \prereq 50,45,45,30:
+\reqhalfcourse 65,30:{2513}{Informat.\\Systems}{TTh 1:00}
+ \coreq 50,45,65,30:
+\mini 10,26:{1083}
+\reqhalfcourse 10,20:{2333}{Computab.\,\&\\Formal\,Lang.}{TTh 11:30}
+ \prereq 10,26,10,20:
+ \prereq 25,40,10,20:
+\reqhalfcourse 45,20:{2013}{Software\\Engineer.\,I}{MWF 11:30}
+ \prereq 45,30,45,20:
+\halfcourse 55,20:{2685}{\texttt{C++}\\Program.}{no}
+ \prereq 45,30,55,20:
+\mini 21,16:{2013}
+\reqhalfcourse 15,10:{3323}{Data\\Structures}{MWF 10:30}
+ \prereq 21,16,15,10:
+ \prereq 25,40,15,10:
+\reqhalfcourse 25,10:{3813}{Comput.\\Organiz.\,II}{TTh 8:30}
+ \prereq 30,30,25,10:
+\reqhalfcourse 35,10:{3413}{Operating\\Systems\,I}{MWF 9:30}
+ \recomm 45,20,35,10:
+ \prereq 30,30,35,10:
+\halfcourse 45,10:{3013}{Software\\Engineer.\,II}{MWF 11:30}
+ \prereq 45,20,45,10:
+\halfcourse 58,10:{3513}{Database\\Mngt.\,Sys.\,I}{MWF 8:30 pm}
+ \prereq 45,20,58,10:
+ \prereq 65,30,58,10:
+\reqhalfcourse 70,10:{3503}{Sys.\,Anal.\\\&\,Design}{TTh 10:00}
+ \prereq 65,30,70,10:
+\end{chart}
+\vspace*{6ex}
+\caption{A Prerequisite Chart with a Coordinate Grid}
+\label{grid}
+\end{figure}
diff --git a/Master/texmf-dist/doc/latex/prerex/doc/prerex.pdf b/Master/texmf-dist/doc/latex/prerex/doc/prerex.pdf
new file mode 100644
index 00000000000..09ad867ce0b
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/doc/prerex.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/prerex/doc/prerex.sty.7 b/Master/texmf-dist/doc/latex/prerex/doc/prerex.sty.7
new file mode 100644
index 00000000000..87ef4f540fa
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/doc/prerex.sty.7
@@ -0,0 +1,437 @@
+.TH PREREX.STY 7 2010-06-25 "prerex.sty-6.0" ""
+.SH NAME
+prerex.sty \- a LaTeX document style for prerequisite charts
+.SH DESCRIPTION
+.B prerex.sty
+defines macros that
+.B [pdf]latex
+can use
+to draw charts consisting of labelled course boxes linked by arrows
+that represent pre- and co-requisite requirements.
+In addition to the usual
+.B [pdf]latex
+output, auxiliary files will be generated containing image-map data for the
+hyperlinked nodes in the diagram and a shell script to crop a PNG image generated from
+a Postscript or PDF chart.
+.P
+If the source file satisfies the constraints
+of the
+.BR prerex (5)
+format, a chart description may be edited using the
+.BR prerex (1)
+interactive editor (as well as any conventional text editor).
+.SH TERMINOLOGY
+A prerequisite chart consists of several
+.I course boxes,
+linked by
+.I arrows.
+Courses are either
+.I half
+or
+.I full,
+and may be
+.I required.
+Each course box can contain a course
+.I code
+(upper left corner),
+a course
+.I title
+(lower half),
+and
+.I timetable
+information
+(upper right corner).
+An arrow can be either a
+.I prerequisite
+(solid),
+a
+.I corequisite
+(dotted),
+or
+.I recommended
+(dashed).
+When a conventional arrow would be inappropriate, it is possible to use
+a
+.I mini
+course "box" (consisting of just a course code) just above a target box.
+An arbitrary line of text may be placed anywhere on the chart.
+.SH COORDINATE SYSTEM
+A conventional two-dimensional
+Cartesian coordinate system is used to specify the locations of
+diagram elements.
+The
+origin (where
+.I x = 0
+and
+.IR "y = 0" )
+is at the lower-left corner of the diagram.
+The diagram height is configurable; the width is determined by
+the values of
+.I \etextwidth
+and
+an adjustable
+.I \eunit
+length, which defines the absolute value of a coordinate unit.
+It is possible to put a coordinate grid with labelled axes
+in the background of a chart.
+The coordinates of a
+.I box,
+.I mini,
+or
+.I text-line
+are those of its centre point.
+An
+.I arrow
+is described by the
+coordinates of the centre points of its source and target boxes/minis/text-lines.
+.SH USAGE
+The command
+.B \eusepackage{prerex}
+should appear in the document preamble.
+This will define a LaTeX environment
+.IP
+.BI \ebegin{chart} " ... " \eend{chart}
+.LP
+within which the following commands may be used
+to produce course boxes, minis, text-lines, and arrows.
+The order of commands is not significant except
+that the commands for the source and target boxes of an arrow should
+.I precede
+the command for the arrow, and the
+.B grid
+command should precede all other commands.
+.SH COURSE BOXES
+The commands producing course boxes have the following forms:
+.IP
+.BI \ehalfcourse " x,y" :{ code }{ title }{ timetable }
+.IP
+.BI \efullcourse " x,y" :{ code }{ title }{ timetable }
+.IP
+.BI \ereqhalfcourse " x,y" :{ code }{ title }{ timetable }
+.IP
+.BI \ereqfullcourse " x,y" :{ code }{ title }{ timetable }
+.LP
+where
+.I x,y
+are the coordinates of the
+.I centerpoint
+of the box, relative to the origin
+of the coordinate system at the lower-left corner of the diagram.
+The
+.I code,
+.I title,
+and
+.I timetable
+arguments are arbitrary (well-bracketed) text, possibly with LaTeX markup.
+.SH MINI COURSE BOXES AND TEXT LINES
+A mini course "box" is produced by a command of the form
+.IP
+.BI \emini " x,y" :{ code }
+.LP
+The following instruction places a line of text centered at the coordinates:
+.IP
+.BI \etext " x,y" :{ text-line }
+.LP
+There are several differences between minis and text-lines.
+The maximum length allowed for a course-code may be less than that
+for a text-line. A sans-serif font and a reduced font size is used for a course-code. A course-code
+may be hyperlinked but a text-line is not (except when the coordinate grid is on).
+A
+.B \eparbox
+command
+may be used in the
+.I text-line
+argument if more than one line is desired.
+.SH ARROWS
+Arrows between course boxes (or from a mini or text-line to a course box) are produced
+by commands of the form
+.IP
+.BI \eprereq " x0,y0,x1,y1" :
+.IP
+.BI \ecoreq " x0,y0,x1,y1" :
+.IP
+.BI \erecomm " x0,y0,x1,y1" :
+.LP
+These produce, respectively, solid, dotted, and dashed arrows from
+the course box (or mini or text-line) centered at coordinates
+.I x0,y0
+to the course box centered at coordinates
+.I x1,y1.
+.PP
+Arrows by default have a
+non-zero curvature (unless they are very short). It is possible to override the default curvature
+for a particular arrow by using
+the instructions
+.IP
+.BI \eprereqc " x0,y0,x1,y1;c" :
+.IP
+.BI \ecoreqc " x0,y0,x1,y1;c" :
+.IP
+.BI \erecommc " x0,y0,x1,y1;c" :
+.LP
+where
+.I c
+is an integer in the range 0-100 specifying the desired curvature; for example,
+.IR c= 0
+will produce a
+.I straight
+arrow. To change the default curvature, the user program may redefine the
+.B \eDefaultCurvature
+command.
+.SH WEB LINKS
+Course boxes (including minis) may be hyperlinked.
+The default URL for course boxes is
+.IR course-code .html
+where
+.I course-code
+is
+the
+.I code
+argument
+of the course box. The URL scheme may be changed by the user
+by re-defining the
+.B \eCourseURL
+command.
+.SH COORDINATE GRID
+The following command produces a coordinate grid, which is
+useful for editing a diagram:
+.IP
+.B \egrid
+.LP
+This is normally placed before all the other chart commands so that
+grid lines are in the background, covered by course boxes, minis, and arrows.
+The
+.B \egrid
+command
+also redefines the
+.B \eCourseURL
+command
+so that,
+if the mouse cursor is placed over a box or mini in (some) PDF viewers,
+the
+.I coordinates
+of the box, mini, or text-line will be displayed
+as follows:
+in the status bar in
+.BR xpdf
+and
+.BR gpdf ,
+and in a "tooltip" in recent versions of
+.BR kpdf " (now re-named"
+.BR okular ),
+.BR evince ,
+and
+the Adobe Reader.
+Similarly, the coordinates of the source and target boxes of arrows
+are displayed if the mouse hovers over the mid-point of an arrow,
+Such coordinate displays make it easier to edit chart descriptions.
+.PP
+The
+.B prerex
+package at
+.B http://www.ctan.org/tex-archive/graphics/prerex/
+has a patch for
+.BR kpdf / okular (1)
+to make it display URIs in tooltips and also capture coordinates of course boxes, arrows and
+background points in the X selection clipboard (for pasting into a
+command being composed at the
+.BR prerex (1)
+prompt). There is also a GUI frontend
+.BR vprerex (1)
+to the
+.BR prerex (1)
+editor which incorporates a minimalistic prerex-enabled PDF viewer.
+.SH STAND-ALONE COMMANDS
+The following commands may be used outside a
+.B chart
+environment, such as in the explanatory notes for a chart:
+.IP
+.B \esolidarrow
+.IP
+.B \edottedarrow
+.IP
+.B \edashedarrow
+.IP
+.B \elightbox
+.IP
+.B \eboldbox
+.LP
+.SH CONFIGURATION
+The following are defined by the style file but may be re-defined by the
+user:
+.IP
+.BI \enewcommand{\eDefaultCurvature}{ 20 }
+.LP
+where the argument should be in the range 0-100; 0 means no curvature.
+.IP
+.BI \enewcommand{\eCourseURL}[3]{ #3.html }
+.LP
+where the arguments supplied at the call are the
+.I x
+and
+.I y
+coordinates of the box or mini and the course code.
+.IP
+.BI \enewcommand{\ebackground}{ LightYellow }
+.LP
+where
+.I LightYellow
+is defined by
+.IP
+.BI \edefinecolor{LightYellow}{ rgb }{ "1.0, 1.0, 0.878431" }
+.IP
+.BI \esetlength{\eunit}{ 5.7816pt }
+.LP
+which defines the absolute size of a coordinate unit; this yields 10 pixels per
+coordinate unit if the chart is converted to an image at 125 dpi.
+.IP
+.BI \enewcommand{\edpi}{ 125 }
+.IP
+.BI \enewcommand{\ePixelsPerUnit}{ 10 }
+.LP
+These must be re-defined together if the image-map data are to be correct.
+.IP
+.BI \esetcounter{diagheight}{ 75 }
+.LP
+which is the
+.IR y -coordinate
+of the top of the diagram (reduced to 65 in landscape mode);
+the nominal diagram width is
+.IR \etextwidth " / " \eunit " + " 10.
+.P
+The following define the thicknesses of the three kinds of arrows,
+and the thickness of bold boxes:
+.IP
+.BI \enewcommand{\esolidwidth}{ 0.5pt }
+.IP
+.BI \enewcommand{\edottedwidth}{ 0.8pt }
+.IP
+.BI \enewcommand{\edashedwidth}{ 0.5pt }
+.IP
+.BI \enewcommand{\eboldwidth}{ 1.0pt }
+.LP
+.P
+The following command is used to change to a smaller size for course codes,
+timetable information, and mini-course codes:
+.IP
+.BI \enewcommand{\esmallersize} {\erelsize{-3}}
+.LP
+.SH DEPEDENCIES
+This implementation of
+.B prerex.sty
+uses
+.B pgf
+(version 1.18 or later)
+with add-on package
+.B tikz.
+The following additional packages are used:
+.B relsize,
+.B calc,
+.B ifthen,
+.B multido,
+.B textcomp,
+.B zref-savepos
+and
+.B hyperref.
+.I Either
+.BR pdflatex (1)
+.I or
+.BR latex (1)
+followed by
+.BR dvips (1)
+(and possibly
+.BR ps2pdf (1))
+may be used.
+.P
+To convert a chart to a compact but reasonably high-quality image, it is suggested to use the
+.BR convert (1)
+tool of
+.BR ImageMagick (1)
+as follows:
+.IP
+.B convert
+.I -density 125 chart.ps chart.png
+.LP
+or
+.IP
+.B convert
+.I -density 125 chart.pdf chart.png
+.LP
+The density parameter specifies the number of pixels per inch; if this is too small, the
+image is of poor quality, and if it is too large, the image file is too big.
+By default, the shell script generated by
+.B prerex.sty
+crops the image at the southeast corner.
+It is possible to use a PNG compression application such as
+.BR optipng (1)
+to reduce the file-size of the cropped image (without loss of quality).
+
+.SH IMPLEMENTATION DETAILS
+.P
+To improve the appearance, boxes are drawn with slightly rounded corners. The half-course
+boxes are assigned a minimum height to give a more uniform appearance to horizontal
+rows of such boxes.
+The mini and text boxes have white frames and their
+fill colour is white, which is assumed to be the background colour of the chart.
+A text box is not normally hyperlinked; however, if the coordinate grid is
+on, it is hyperlinked and its chart coordinates are encoded in the URI.
+.P
+Arrows with a small height and arrows whose
+source and target points have equal x or y coordinates are always draw straight
+(using a specialized and simpler macro) unless an explicit
+non-zero curvature argument is provided.
+If the coordinate grid is on, a hyperlink with the source and target coordinates is placed
+at the mid-point of the arrow.
+A wider background white edge is drawn below an arrow to
+improve the appearance
+of crossing arrows; the background also
+ensures visibility of the
+arrow when the coordinate grid is on.
+A thin white arrow (with a visible
+arrowhead) is drawn beneath the visible arrow to obtain a thin arrowhead.
+.P
+When the coordinate grid is drawn, the
+.B CourseURL
+command
+is re-defined to pass node coordinates in URIs. Also,
+two ``anchor'' hyperlinks are inserted at the southwest and northeast corners
+of the diagram to allow prerex-enabled
+PDF viewers to compute chart coordinates.
+.P
+To support HTML versions of charts,
+.B prerex.sty
+generates a script to crop a chart image at the southeast corner, allowing
+descriptive notes below the chart to be treated as ordinary text. Also,
+it generates image-map data for use with an HTML image map. To
+obtain absolute page coordinates, the
+.B zsavepos,
+.B zposx
+and
+.B zposy
+commands are used; the page coordinates are converted into pixel coordinates
+for cropping and image-map use.
+.SH LICENSE
+.B prerex.sty
+and this document may be distributed and/or modified under the
+conditions of the LaTeX Project Public License.
+.SH AUTHOR
+R. D. Tennent (rdt@cs.queensu.ca)
+.SH SEE ALSO
+.BR ImageMagick (1),
+.BR convert (1).
+.BR dvips (1),
+.BR evince (1),
+.BR gpdf (1),
+.BR kpdf (1),
+.BR latex (1),
+.BR okular (1),
+.BR optipng (1),
+.BR pdflatex (1),
+.BR prerex (1),
+.BR prerex (5),
+.BR ps2pdf (1),
+.BR tikz (1),
+.BR tgf (1),
+.BR vprerex (1),
+and
+.BR xpdf (1).
diff --git a/Master/texmf-dist/doc/latex/prerex/doc/prerex.tex b/Master/texmf-dist/doc/latex/prerex/doc/prerex.tex
new file mode 100644
index 00000000000..84488e50ff5
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/doc/prerex.tex
@@ -0,0 +1,524 @@
+\documentclass[10pt]{article}
+\usepackage{mathpazo}
+\usepackage[scaled=0.9]{helvet}
+\usepackage{fullpage}
+\usepackage{prerex}
+%\def\LaTeX{\mbox{LaTeX}}
+\begin{document}
+
+\title{\textsf{prerex.sty}: Prerequisite Charts in \LaTeX\\{\large Version 6.0}}
+\author{R. D. Tennent\\\texttt{rdt@cs.queensu.ca}}
+\date{\today}
+\maketitle
+\thispagestyle{empty}
+
+\section{Description}
+\texttt{prerex.sty}
+defines macros that
+[pdf]\LaTeX\
+can use
+to draw charts consisting of labelled course boxes linked by arrows
+that represent pre- and co-requisite requirements; see
+the example chart in Figure~\ref{chart} on page~\pageref{chart}.
+In addition to the usual
+[pdf]\LaTeX\
+output, auxiliary files will be generated containing image-map data for the
+hyperlinked nodes in the diagram and a shell script for cropping a PNG image
+obtained from the [pdf]\LaTeX\ output.
+
+If the source file satisfies the constraints
+of the
+\textsf{prerex(5)}
+format, a chart description may be edited using the
+\textsf{prerex(1)}
+interactive editor (as well as any conventional text editor).
+
+\begin{figure}
+\setcounter{diagheight}{40}
+\begin{chart}\sl
+\text 15,40:{\textsf{\textbf{\Large Computer Science}}}
+\reqfullcourse 50,35:{1083}{Comput.\,Sci.\\Concepts}{TTh 10:00}
+\reqhalfcourse 25,30:{1303}{Discrete\\Structures}{MWF 9:30}
+\reqhalfcourse 30,20:{2813}{Computer\\Organiz.\,I}{MWF 8:30}
+ \prereq 50,35,30,20:
+ \prereq 25,30,30,20:
+\reqhalfcourse 45,20:{2023}{Procedural\\Prog.\,Devel.}{MWF 2:30}
+ \prereq 50,35,45,20:
+\reqhalfcourse 65,20:{2513}{Informat.\\Systems}{TTh 1:00}
+ \coreq 50,35,65,20:
+\mini 10,16:{1083}
+\reqhalfcourse 10,10:{2333}{Computab.\,\&\\Formal\,Lang.}{TTh 11:30}
+ \prereq 25,30,10,10:
+ \prereq 10,16,10,10:
+\reqhalfcourse 45,10:{2013}{Software\\Engineer.\,I}{MWF 11:30}
+ \prereq 45,20,45,10:
+\halfcourse 55,10:{2685}{\texttt{C++}\\Program.}{no}
+ \prereq 45,20,55,10:
+\mini 21,6:{2013}
+\reqhalfcourse 15,0:{3323}{Data\\Structures}{MWF 10:30}
+ \prereq 25,30,15,0:
+ \prereq 21,6,15,0:
+\reqhalfcourse 25,0:{3813}{Comput.\\Organiz.\,II}{TTh 8:30}
+ \prereq 30,20,25,0:
+\reqhalfcourse 35,0:{3413}{Operating\\Systems\,I}{MWF 9:30}
+ \prereq 30,20,35,0:
+ \recomm 45,10,35,0:
+\halfcourse 45,0:{3013}{Software\\Engineer.\,II}{MWF 11:30}
+ \prereq 45,10,45,0:
+\halfcourse 58,0:{3513}{Database\\Mngt.\,Sys.\,I}{MWF 8:30 pm}
+ \prereq 65,20,58,0:
+ \prereq 45,10,58,0:
+\reqhalfcourse 70,0:{3503}{Sys.\,Anal.\\\&\,Design}{TTh 10:00}
+ \prereq 65,20,70,0:
+\end{chart}
+
+\paragraph{Notes}
+\begin{itemize}
+\item
+A solid arrow \solidarrow\ indicates a required prerequisite,
+a dotted arrow \dottedarrow\
+indicates a corequisite (to be taken before or concurrently), and a
+dashed arrow \dashedarrow\ indicates a recommended prerequisite.
+Core courses are in \boldbox\ boxes;
+other courses (i.e.,~options or prerequisites)
+are in \lightbox\ boxes.
+\item Timetable abbreviations: M, T, W, Th, F$=$Mon, Tue, Wed, Thur, Fri, resp.; no$=$not offered.
+\item \dots
+\end{itemize}
+\caption{A Prerequisite Chart}
+\label{chart}
+\end{figure}
+\section{Terminology}
+A prerequisite chart consists of a number of
+\emph{course boxes},
+linked by
+\emph{arrows}.
+Courses are either
+\emph{half}
+or
+\emph{full},
+and may be
+\emph{required}.
+Each course box can contain a course
+\emph{code}
+(upper left corner),
+a course
+\emph{title}
+(lower half),
+and
+\emph{timetable}
+information
+(upper right corner).
+An arrow can be either a \emph{prerequisite} (solid),
+a \emph{corequisite} (dotted),
+or
+\emph{recommended} (dashed).
+When a conventional arrow would be inappropriate, it is possible to use
+a
+\emph{mini}
+course ``box'' (consisting of just a course code) just above a target box.
+A line of text may be placed anywhere on the chart.
+\section{Coordinate System}
+A conventional two-dimensional
+Cartesian coordinate system is used to specify the locations of
+diagram elements.
+The
+origin (where
+$x = 0$
+and
+$y = 0$)
+is at the lower-left corner of the diagram.
+The diagram height is configurable; the width is determined by
+the values of
+\verb|\textwidth|
+and
+an adjustable
+\verb|\unit|
+length, which defines the absolute value of a coordinate unit.
+It is possible to put a coordinate grid with labelled axes
+in the background of a chart.
+The coordinates of a
+\emph{box,}
+\emph{mini,}
+or
+\emph{text-line}
+are those of its centre point.
+An
+\emph{arrow}
+is described by the
+coordinates of the centre points of its source and target boxes/minis/text-lines.
+
+\section{Usage}
+The command
+\verb|\usepackage{prerex}|
+should appear in the document preamble.
+This will define a \LaTeX\ environment
+\begin{list}{}{}
+\item \verb|\begin{chart}|\quad$\cdots$\quad \verb|\end{chart}|
+\end{list}
+within which the commands described in the following sub-sections may be used
+to produce course boxes, minis, text-lines, and arrows.
+The order of commands is not significant except
+that the commands for the source and target boxes of an arrow should
+precede
+the command for the arrow, and the \verb|\grid| command, if present, should precede
+other chart commands.
+
+\subsection{Course Boxes}
+The commands producing course boxes have the following forms:
+\begin{list}{}{}
+\item \verb|\halfcourse | $x,y$ \verb|:{| \emph{code} \verb|}{| \emph{title} \verb|}{| \emph{timetable} \verb|}|
+\item \verb|\reqhalfcourse | $x,y$ \verb|:{| \emph{code} \verb|}{| \emph{title} \verb|}{| \emph{timetable} \verb|}|
+\item \verb|\fullcourse | $x,y$ \verb|:{| \emph{code} \verb|}{| \emph{title} \verb|}{| \emph{timetable} \verb|}|
+\item \verb|\reqfullcourse | $x,y$ \verb|:{| \emph{code} \verb|}{| \emph{title} \verb|}{| \emph{timetable} \verb|}|
+\end{list}
+where
+$x,y$
+are the coordinates of the
+centerpoint
+of the box, relative to the origin
+of the coordinate system at the lower-left corner of the diagram.
+The
+\emph{code},
+\emph{title},
+and
+\emph{timetable}
+arguments are arbitrary (well-bracketed) text, possibly with \LaTeX\ markup.
+
+\subsection{Mini Course Boxes and Text-Lines}
+A mini course ``box'' is produced by a command of the form
+\begin{list}{}{}
+\item \verb|\mini| $x,y$ \verb|:{| \emph{code} \verb|}|
+\end{list}
+A text-line is produced by a command of the form
+\begin{list}{}{}
+\item \verb|\text| $x,y$ \verb|:{| \emph{line of text} \verb|}|
+\end{list}
+There are several differences between minis and text-lines.
+The maximum length allowed for a course-code may be less than that
+for a text-line. A sans-serif font and a reduced font size is
+used for a course-code. A course-code
+may be hyperlinked but a text-line is not (except when the coordinate grid is on).
+A \verb|\parbox| command may be used if more than one line is desired.
+
+
+\subsection{Arrows}
+Arrows between course boxes (or minis or text-lines) are produced
+by commands of the form
+\begin{list}{}{}
+\item \verb|\prereq| $ x_0,y_0,x_1,y_1$\verb|:|
+\item \verb|\coreq| $ x_0,y_0,x_1,y_1$\verb|:|
+\item \verb|\recomm| $ x_0,y_0,x_1,y_1$\verb|:|
+\end{list}
+These produce, respectively, solid, dotted, and dashed arrows from
+the course box (or mini or text-line) centered at coordinates
+$x_0,y_0$
+to the entity centered at coordinates
+$x_1,y_1$.
+
+Arrows by default have a
+non-zero curvature (unless they are very short). It is possible to override the default curvature
+for a particular arrow by using
+the instructions
+\begin{list}{}{}
+\item \verb|\prereqc| $ x_0,y_0,x_1,y_1;c$\verb|:|
+\item \verb|\coreqc| $ x_0,y_0,x_1,y_1;c$\verb|:|
+\item \verb|\recommc| $ x_0,y_0,x_1,y_1;c$\verb|:|
+\end{list}
+where
+$c$
+is an integer in the range $0$--$100$ specifying the desired curvature; for example,
+$c= 0$
+will produce a
+straight
+arrow. To change the default curvature for all arrows, the user program may redefine the
+\verb|\DefaultCurvature|
+command.
+\subsection{Web Links}
+\label{WebLinks}
+Course boxes and minis may be hyperlinked.
+The default URL for course boxes is
+\emph{course-code}\verb|.html|
+where
+\emph{course-code}
+is
+the
+\emph{code}
+argument
+of the course box. The URL scheme may be changed by the user
+by re-defining the
+\verb|\CourseURL|
+command; see Section~\ref{Configuration}.
+\subsection{Coordinate Grid}
+The following command produces a coordinate grid with labelled axes, which is
+useful while editing a diagram:
+\begin{list}{}{}
+\item \verb|\grid|
+\end{list}
+This is normally placed before all the other chart commands so that
+grid lines are in the background, covered by course boxes, minis, text-lines, and arrows,
+as in Figure~\ref{grid} on page~\pageref{grid}.
+
+The \verb|\grid| command
+also redefines the \verb|CourseURL| command
+so that, in suitable PDF viewers,
+if the mouse cursor is placed over a box, mini, or midpoint of an arrow,
+the \emph{coordinates} of the box/mini/textline (or the coordinates of the source \emph{and} target
+of the arrow) will be displayed
+as follows: in the
+status bar
+in \texttt{xpdf} and \texttt{gpdf}, and in a
+``tooltip'' in recent versions of \texttt{kpdf}/\texttt{okular}, \texttt{evince}, and the Acrobat Reader.
+This coordinate display make it easier to edit chart descriptions.
+
+The
+\texttt{prerex}
+package at
+\url{http://www.ctan.org/tex-archive/graphics/prerex/}
+has a patch for
+\texttt{kpdf} (recently incorporated into \texttt{okular})
+to allow capture coordinates of course boxes,
+arrows, and
+background points in the X selection clipboard (for pasting into a
+command being composed at the
+\texttt{prerex}
+prompt).
+There is also a GUI frontend
+\texttt{vprerex} to the \texttt{prerex}
+editor which incorporates a minimalistic prerex-enabled PDF viewer.
+
+\begin{figure}
+\setcounter{diagheight}{40}
+\begin{chart}\sl
+\grid
+\text 15,40:{\textsf{\textbf{\Large Computer Science}}}
+\reqfullcourse 50,35:{1083}{Comput.\,Sci.\\Concepts}{TTh 10:00}
+\reqhalfcourse 25,30:{1303}{Discrete\\Structures}{MWF 9:30}
+\reqhalfcourse 30,20:{2813}{Computer\\Organiz.\,I}{MWF 8:30}
+ \prereq 25,30,30,20:
+ \prereq 50,35,30,20:
+\reqhalfcourse 45,20:{2023}{Procedural\\Prog.\,Devel.}{MWF 2:30}
+ \prereq 50,35,45,20:
+\reqhalfcourse 65,20:{2513}{Informat.\\Systems}{TTh 1:00}
+ \coreq 50,35,65,20:
+\mini 10,16:{1083}
+\reqhalfcourse 10,10:{2333}{Computab.\,\&\\Formal\,Lang.}{TTh 11:30}
+ \prereq 10,16,10,10:
+ \prereq 25,30,10,10:
+\reqhalfcourse 45,10:{2013}{Software\\Engineer.\,I}{MWF 11:30}
+ \prereq 45,20,45,10:
+\halfcourse 55,10:{2685}{\texttt{C++}\\Program.}{no}
+ \prereq 45,20,55,10:
+\mini 21,6:{2013}
+\reqhalfcourse 15,0:{3323}{Data\\Structures}{MWF 10:30}
+ \prereq 21,6,15,0:
+ \prereq 25,30,15,0:
+\reqhalfcourse 25,0:{3813}{Comput.\\Organiz.\,II}{TTh 8:30}
+ \prereq 30,20,25,0:
+\reqhalfcourse 35,0:{3413}{Operating\\Systems\,I}{MWF 9:30}
+ \recomm 45,10,35,0:
+ \prereq 30,20,35,0:
+\halfcourse 45,0:{3013}{Software\\Engineer.\,II}{MWF 11:30}
+ \prereq 45,10,45,0:
+\halfcourse 58,0:{3513}{Database\\Mngt.\,Sys.\,I}{MWF 8:30 pm}
+ \prereq 45,10,58,0:
+ \prereq 65,20,58,0:
+\reqhalfcourse 70,0:{3503}{Sys.\,Anal.\\\&\,Design}{TTh 10:00}
+ \prereq 65,20,70,0:
+\end{chart}
+\vspace*{2ex}
+\caption{A Prerequisite Chart with a Coordinate Grid}
+\label{grid}
+\end{figure}
+\subsection{Stand-Alone Commands}
+The following commands may be used outside a
+\verb|chart|
+environment, such as in the explanatory notes for a chart:
+\begin{center}
+\begin{tabular}{lc}
+\verb|\solidarrow| & \solidarrow\\
+\verb|\dottedarrow| & \dottedarrow \\
+\verb|\dashedarrow| & \dashedarrow \\
+\verb|\lightbox| & \lightbox \\
+\verb|\boldbox| & \boldbox \\
+\end{tabular}
+\end{center}
+
+\section{Dependencies}
+This implementation of
+\verb|prerex.sty|
+uses
+\verb|pgf|
+(version~1.18 or later)
+with add-on package
+\verb|tikz|.
+The following additional packages are used:
+\verb|multido|,
+\verb|relsize|,
+\verb|calc|,
+\verb|ifthen|,
+\verb|textcomp|,
+\verb|zref-savepos|,
+and
+\verb|hyperref|.
+\emph{Either} \verb\pdflatex\
+\emph{or}
+\verb\latex\ (followed by \verb\dvips\ and, possibly, \verb\ps2pdf\)
+may be used.
+
+\section{Conversion to Portable Network Graphic (PNG) Format}
+
+To convert a chart (in Postscript or PDF format) to a reasonably high-quality image, it is suggested to use the
+\verb|convert| tool of the
+\verb|ImageMagick| package as follows:
+\begin{verbatim}
+ convert -density 125 chart.ps chart.png
+\end{verbatim}
+or
+\begin{verbatim}
+ convert -density 125 chart.pdf chart.png
+\end{verbatim}
+The density parameter specifies the number of pixels per inch; if this is too small, the
+image is of poor quality, and if it is too large, the image file is too big.
+By default, the shell script generated by \texttt{prerex.sty} crops the image at the southeast corner.
+It is possible to use a PNG compression application such as
+\texttt{optipng} to reduce the file-size of the cropped image (without loss of quality).
+
+An auxiliary file
+containing image-map data for the hyperlinked nodes in the chart is also generated;
+consult a reference on the HTML language for an explanation of (client-side) image maps.
+
+\section{Installation}
+
+\begin{enumerate}
+ \item install the most recent version of
+\verb\pgf\ from \url{http://sourceforge.net/projects/pgf/}.
+ \item copy \verb|prerex.sty| to \emph{your-texmf-tree}\verb|/tex/latex/misc|
+ \item copy \verb|doc/prerex.{tex,pdf}| to \emph{your-texmf-tree}\verb|/doc/latex/misc|
+ \item if necessary, refresh the \TeX\ database (e.g., \verb|texhash|)
+ \item copy \verb|man/prerex.sty.7| to sub-directory \verb|man7| of a \verb|man| directory on your
+ \verb|MANPATH|
+ \item test by doing
+
+\begin{verbatim}
+$ man 7 prerex.sty
+$ make chart.pdf
+\end{verbatim}
+
+
+\end{enumerate}
+
+\section{Configuration}
+\label{Configuration}
+The following are defined by the style file but may be re-defined by the
+user:
+\begin{list}{}{}
+\item \verb|\newcommand{\DefaultCurvature}{20}|
+\end{list}
+where the argument should be in the range $0$--$100$; $0$ means no curvature.
+\begin{list}{}{}
+\item \verb|\newcommand{\CourseURL}[3]{#3.html}|
+\end{list}
+where the arguments supplied at the call are the $x$ and $y$ coordinates
+of the box or mini and the course code.
+\begin{list}{}{}
+\item \verb|\newcommand{\background}{LightYellow}|
+\end{list}
+where
+\verb|LightYellow|
+is defined by
+\begin{list}{}{}
+\item \verb|\definecolor{LightYellow}{rgb}{1.0, 1.0, 0.878431}|
+\end{list}
+\begin{list}{}{}
+\item \verb|\setlength{\unit}{5.7816pt}|
+\end{list}
+which defines the absolute size of a coordinate unit;
+this yields 10 pixels per
+coordinate unit if the chart is converted to an image at 125 dpi.
+\begin{list}{}{}
+\item \verb|\newcommand{\dpi}{125}|
+\item \verb|\newcommand{\PixelsPerUnit}{10}|
+\end{list}
+These have to re-defined together if the image-map data are to be correct.
+\begin{list}{}{}
+\item \verb|\setcounter{diagheight}{75}|
+\end{list}
+which is the
+$y$-coordinate
+of the top of the diagram (reduced to $65$ in landscape mode);
+the nominal diagram width is
+\verb|\textwidth|~$\div$~\verb|\unit|~$+ 10$.
+
+
+The following define the thicknesses of the three kinds of arrows,
+and the thickness of bold boxes:
+\begin{list}{}{}
+\item
+\verb|\newcommand{\solidwidth}{0.5pt}|
+\item
+\verb|\newcommand{\dottedwidth}{0.8pt}|
+\item
+\verb|\newcommand{\dashedwidth}{0.5pt}|
+\item
+\verb|\newcommand{\boldwidth}{1.0pt}|
+\end{list}
+
+The following command is used to change to a smaller size for course codes,
+timetable information, and mini-course codes:
+\begin{list}{}{}
+\item
+\verb|\newcommand{\smallersize}{\relsize{-3}}|
+\end{list}
+
+\section{Implementation Details}
+
+\subsection{Boxes}
+
+To improve the appearance, boxes are drawn with slightly rounded corners. The half-course
+boxes are assigned a minimum height to give a more uniform appearance to horizontal
+rows of such boxes.
+The mini and text boxes have white frames and their
+fill colour is white, which is assumed to be the background colour of the chart.
+A text box is not normally hyperlinked; however, if the coordinate grid is
+on, it is hyperlinked and its chart coordinates are encoded in the URI.
+
+\subsection{Arrows}
+Arrows with a small height and arrows whose
+source and target points have equal x or y coordinates are always draw straight
+(using a specialized and simpler macro) unless an explicit
+non-zero curvature argument is provided.
+
+If the coordinate grid is on, a hyperlink with the source and target coordinates is placed
+at the mid-point of the arrow.
+
+A wider background white edge is drawn below an arrow to
+improve the appearance
+of crossing arrows; the background also
+ensures visibility of the
+arrow when the coordinate grid is on.
+A thin white arrow (with a visible
+arrowhead) is drawn beneath the visible arrow to obtain a thin arrowhead.
+
+\subsection{Coordinate Grid and Associated Changes}
+When the coordinate grid is drawn, the \texttt{CourseURL} command
+is re-defined to pass node coordinates in URIs. Also,
+two ``anchor'' hyperlinks are inserted at the southwest and northeast corners
+of the diagram to allow prerex-enabled
+PDF viewers to compute chart coordinates.
+
+\subsection{Chart Images}
+
+To support HTML versions of charts,
+\texttt{prerex.sty}
+generates a script to crop a chart image at the southeast corner, allowing
+descriptive notes below the chart to be treated as ordinary text. Also,
+it generates image-map data for use with an HTML image map. To
+obtain absolute page coordinates, the \texttt{zsavepos}, \texttt{zposx}
+and \texttt{zposy} commands are used; the page coordinates are converted into pixel coordinates
+for cropping and image-map use.
+
+\section{License}
+\verb|prerex.sty|, \verb|prerex.sty.7|, \verb|README.prerex| and this document may be distributed and/or modified under the
+conditions of the \LaTeX\ Project Public License.
+\end{document}
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/README b/Master/texmf-dist/doc/latex/prerex/patches/README
new file mode 100644
index 00000000000..8547e49a3eb
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/README
@@ -0,0 +1,62 @@
+These are patches for kpdf (for qt-3) or okular (for qt-4) that enable
+the following additional feature:
+
+ If the PDF being viewed is a prerex-formatted chart (with the
+ coordinate grid enabled), clicking in a course box/mini or arrow will
+ put the coordinates of the box/mini centre or of the arrow source
+ and target boxes into the X clipboard; the coordinates can then
+ be "pasted" into a command being composed at the prerex prompt by
+ middle-clicking the mouse. Similarly, clicking on any point in the
+ background coordinate grid will put the coordinates of that point
+ into the X clipboard. The "hand" or "arrow" cursor changes to a
+ "crosshair" cursor to signal successful capture of coordinate values
+ (until the mouse moves).
+
+Note that this approach is now deprecated; the previewer is a lightweight
+application which doesn't have to be re-patched every time the KDE version
+changes.
+
+Installation
+
+kpdf/okular is distributed as part of the kdegraphics package. Install
+kdegraphics-x.y.z (and the KDE libraries it depends on), where x.y.z
+is the version number in the name of the patch file. Also obtain the
+sources for the relevant version of kdegraphics, either directly from
+
+ftp://ftp.kde.org/pub/kde/stable/
+
+or using the source package for a distribution. Unpack the source and
+apply any distributor-supplied patches.
+
+Move to the kdegraphics-x.y.z directory and do
+
+ cp -r kpdf kpdf.orig
+
+or
+
+ cp -r okular okular.orig
+
+Copy the patch file to the kdegraphics directory and do
+
+ patch -p0 < patch-file
+
+If the patch is successful, do
+
+ ./configure --prefix=/usr
+
+for kde-3 or
+
+ cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr .
+
+for kde-4.
+
+If the configuration step is successful, move to the (patched)
+kpdf/okular directory and do
+
+ make
+ make install (as root)
+
+You do not have to build and re-install all parts of kdegraphics;
+the "make" and "make install" will build and over-write just the
+kpdf/okular-related portions.
+
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.10.patch b/Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.10.patch
new file mode 100644
index 00000000000..aa2eff80e73
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.10.patch
@@ -0,0 +1,291 @@
+diff -cr kpdf.orig/core/document.cpp kpdf/core/document.cpp
+*** kpdf.orig/core/document.cpp 2007-10-08 05:48:37.000000000 -0400
+--- kpdf/core/document.cpp 2009-09-29 16:56:48.000000000 -0400
+***************
+*** 26,31 ****
+--- 26,32 ----
+ #include <kuserprofile.h>
+ #include <krun.h>
+ #include <kstandarddirs.h>
++ #include <qclipboard.h>
+
+ // local includes
+ #include "document.h"
+***************
+*** 1066,1071 ****
+--- 1067,1082 ----
+
+ case KPDFLink::Browse: {
+ const KPDFLinkBrowse * browse = static_cast< const KPDFLinkBrowse * >( link );
++ if ( browse->url().startsWith( "coord:", false ) )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith( "anchor:", false ) ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+ if ( browse->url().startsWith( "mailto:", false ) )
+ kapp->invokeMailer( browse->url() );
+diff -cr kpdf.orig/core/page.cpp kpdf/core/page.cpp
+*** kpdf.orig/core/page.cpp 2005-09-10 04:18:42.000000000 -0400
+--- kpdf/core/page.cpp 2009-09-29 16:56:48.000000000 -0400
+***************
+*** 13,24 ****
+--- 13,27 ----
+ #include <qmap.h>
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "page.h"
+ #include "pagetransition.h"
+ #include "link.h"
+ #include "conf/settings.h"
+ #include "xpdf/TextOutputDev.h"
++ #include <stdlib.h>
+
+
+ /** class KPDFPage **/
+***************
+*** 172,177 ****
+--- 175,269 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint KPDFPage::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which kpdf has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by kpdf
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint();
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QValueList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Link)
++ {
++ const KPDFLink * link = static_cast< const KPDFLink * >( (*it)->pointer() );
++ if (link)
++ {
++ const KPDFLinkBrowse * browse = dynamic_cast< const KPDFLinkBrowse * >( link );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:", false) )
++ {
++ int comma;
++ QString xs;
++ NormalizedRect * r = (*it);
++ QRect unnormalized;
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.find(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ unnormalized = r->geometry(widthPage, heightPage);
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(QCOORD_MIN, QCOORD_MIN);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
+ const KPDFPageTransition * KPDFPage::getTransition() const
+ {
+ return m_transition;
+diff -cr kpdf.orig/core/page.h kpdf/core/page.h
+*** kpdf.orig/core/page.h 2005-09-10 04:18:42.000000000 -0400
+--- kpdf/core/page.h 2009-09-29 16:56:48.000000000 -0400
+***************
+*** 120,125 ****
+--- 120,128 ----
+ void deletePixmapsAndRects();
+ void deleteHighlights( int s_id = -1 );
+
++ // computes the factor that scales from pixel coordinates to chart coordinates:
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
+ private:
+ friend class PagePainter;
+ int m_number, m_rotation;
+diff -cr kpdf.orig/shell/main.cpp kpdf/shell/main.cpp
+*** kpdf.orig/shell/main.cpp 2008-08-19 14:12:37.000000000 -0400
+--- kpdf/shell/main.cpp 2009-09-29 16:56:48.000000000 -0400
+***************
+*** 19,25 ****
+ #include <klocale.h>
+
+ static const char description[] =
+! I18N_NOOP("kpdf, a kde pdf viewer based on xpdf");
+
+ static const char version[] = "0.5.10";
+
+--- 19,25 ----
+ #include <klocale.h>
+
+ static const char description[] =
+! I18N_NOOP("prerex-enabled kpdf, a kde pdf viewer based on xpdf for use with the prerex editor");
+
+ static const char version[] = "0.5.10";
+
+Only in kpdf/shell: main.cpp.orig
+diff -cr kpdf.orig/shell/shell.cpp kpdf/shell/shell.cpp
+*** kpdf.orig/shell/shell.cpp 2007-05-14 03:39:31.000000000 -0400
+--- kpdf/shell/shell.cpp 2009-09-29 16:56:48.000000000 -0400
+***************
+*** 34,39 ****
+--- 34,40 ----
+ #include <kparts/componentfactory.h>
+ #include <kio/netaccess.h>
+ #include <kmainwindowiface.h>
++ #include <kstatusbar.h>
+
+ // local includes
+ #include "shell.h"
+***************
+*** 75,81 ****
+--- 76,86 ----
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+ setupGUI(Keys | Save);
++ createStandardStatusBarAction();
++ setupGUI(ToolBar | Keys | Save | StatusBar );
+ createGUI(m_part);
++ m_statusBar = statusBar();
++ m_statusBar->message("This is prerex-enabled kpdf.", 8000);
+ m_showToolBarAction = static_cast<KToggleAction*>(toolBarMenuAction());
+ }
+ }
+diff -cr kpdf.orig/shell/shell.h kpdf/shell/shell.h
+*** kpdf.orig/shell/shell.h 2006-10-01 13:25:15.000000000 -0400
+--- kpdf/shell/shell.h 2009-09-29 16:56:48.000000000 -0400
+***************
+*** 103,108 ****
+--- 103,109 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KURL m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ }
+diff -cr kpdf.orig/ui/pageview.cpp kpdf/ui/pageview.cpp
+*** kpdf.orig/ui/pageview.cpp 2007-10-08 05:48:37.000000000 -0400
+--- kpdf/ui/pageview.cpp 2009-09-29 16:56:48.000000000 -0400
+***************
+*** 930,936 ****
+ {
+ d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+ if ( !d->mouseOnRect )
+! setCursor( KCursor::sizeAllCursor() );
+ }
+ break;
+
+--- 930,965 ----
+ {
+ d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+ if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->geometry().left(),
+! click.y() - pageItem->geometry().top(),
+! pageItem->width(),
+! pageItem->height()
+! );
+! if (clickChart.x() == QCOORD_MIN && clickChart.y() == QCOORD_MIN)
+! { // no anchors
+! setCursor( KCursor::sizeAllCursor() );
+! break;
+! }
+! setCursor( KCursor::crossCursor() );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ break;
+
+***************
+*** 1005,1010 ****
+--- 1034,1045 ----
+ // handle click over a link
+ const KPDFLink * link = static_cast< const KPDFLink * >( linkRect->pointer() );
+ d->document->processLink( link );
++ if ( link->linkType() == KPDFLink::Browse )
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ const KPDFLinkBrowse * browse = static_cast< const KPDFLinkBrowse * >( link );
++ if ( browse->url().startsWith( "coord:", false ) )
++ setCursor( KCursor::crossCursor() );
++ }
+ }
+ else
+ {
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.8.patch b/Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.8.patch
new file mode 100644
index 00000000000..c7938219a46
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.8.patch
@@ -0,0 +1,292 @@
+diff -cr kpdf.orig/core/document.cpp kpdf/core/document.cpp
+*** kpdf.orig/core/document.cpp 2007-11-13 09:43:02.000000000 -0500
+--- kpdf/core/document.cpp 2007-11-13 10:26:15.000000000 -0500
+***************
+*** 26,31 ****
+--- 26,32 ----
+ #include <kuserprofile.h>
+ #include <krun.h>
+ #include <kstandarddirs.h>
++ #include <qclipboard.h>
+
+ // local includes
+ #include "document.h"
+***************
+*** 1066,1071 ****
+--- 1067,1082 ----
+
+ case KPDFLink::Browse: {
+ const KPDFLinkBrowse * browse = static_cast< const KPDFLinkBrowse * >( link );
++ if ( browse->url().startsWith( "coord:", false ) )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith( "anchor:", false ) ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+ if ( browse->url().startsWith( "mailto:", false ) )
+ kapp->invokeMailer( browse->url() );
+diff -cr kpdf.orig/core/page.cpp kpdf/core/page.cpp
+*** kpdf.orig/core/page.cpp 2007-11-13 09:43:02.000000000 -0500
+--- kpdf/core/page.cpp 2007-11-13 10:26:15.000000000 -0500
+***************
+*** 13,24 ****
+--- 13,27 ----
+ #include <qmap.h>
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "page.h"
+ #include "pagetransition.h"
+ #include "link.h"
+ #include "conf/settings.h"
+ #include "xpdf/TextOutputDev.h"
++ #include <stdlib.h>
+
+
+ /** class KPDFPage **/
+***************
+*** 172,177 ****
+--- 175,269 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint KPDFPage::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which kpdf has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by kpdf
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint();
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QValueList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Link)
++ {
++ const KPDFLink * link = static_cast< const KPDFLink * >( (*it)->pointer() );
++ if (link)
++ {
++ const KPDFLinkBrowse * browse = dynamic_cast< const KPDFLinkBrowse * >( link );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:", false) )
++ {
++ int comma;
++ QString xs;
++ NormalizedRect * r = (*it);
++ QRect unnormalized;
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.find(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ unnormalized = r->geometry(widthPage, heightPage);
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(QCOORD_MIN, QCOORD_MIN);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
+ const KPDFPageTransition * KPDFPage::getTransition() const
+ {
+ return m_transition;
+diff -cr kpdf.orig/core/page.h kpdf/core/page.h
+*** kpdf.orig/core/page.h 2007-11-13 09:43:02.000000000 -0500
+--- kpdf/core/page.h 2007-11-13 10:26:15.000000000 -0500
+***************
+*** 120,125 ****
+--- 120,128 ----
+ void deletePixmapsAndRects();
+ void deleteHighlights( int s_id = -1 );
+
++ // computes the factor that scales from pixel coordinates to chart coordinates:
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
+ private:
+ friend class PagePainter;
+ int m_number, m_rotation;
+diff -cr kpdf.orig/shell/main.cpp kpdf/shell/main.cpp
+*** kpdf.orig/shell/main.cpp 2007-11-13 09:43:02.000000000 -0500
+--- kpdf/shell/main.cpp 2007-11-13 10:26:15.000000000 -0500
+***************
+*** 19,25 ****
+ #include <klocale.h>
+
+ static const char description[] =
+! I18N_NOOP("kpdf, a kde pdf viewer based on xpdf");
+
+ static const char version[] = "0.5.8";
+
+--- 19,25 ----
+ #include <klocale.h>
+
+ static const char description[] =
+! I18N_NOOP("prerex-enabled kpdf, a kde pdf viewer based on xpdf for use with the prerex editor");
+
+ static const char version[] = "0.5.8";
+
+Only in kpdf/shell: main.cpp.orig
+diff -cr kpdf.orig/shell/shell.cpp kpdf/shell/shell.cpp
+*** kpdf.orig/shell/shell.cpp 2007-11-13 09:43:02.000000000 -0500
+--- kpdf/shell/shell.cpp 2007-11-13 10:26:15.000000000 -0500
+***************
+*** 34,39 ****
+--- 34,40 ----
+ #include <kparts/componentfactory.h>
+ #include <kio/netaccess.h>
+ #include <kmainwindowiface.h>
++ #include <kstatusbar.h>
+
+ // local includes
+ #include "shell.h"
+***************
+*** 75,81 ****
+--- 76,86 ----
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+ setupGUI(Keys | Save);
++ createStandardStatusBarAction();
++ setupGUI(ToolBar | Keys | Save | StatusBar );
+ createGUI(m_part);
++ m_statusBar = statusBar();
++ m_statusBar->message("This is prerex-enabled kpdf.", 8000);
+ m_showToolBarAction = static_cast<KToggleAction*>(toolBarMenuAction());
+ }
+ }
+diff -cr kpdf.orig/shell/shell.h kpdf/shell/shell.h
+*** kpdf.orig/shell/shell.h 2007-11-13 09:43:02.000000000 -0500
+--- kpdf/shell/shell.h 2007-11-13 10:26:15.000000000 -0500
+***************
+*** 103,108 ****
+--- 103,109 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KURL m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ }
+diff -cr kpdf.orig/ui/pageview.cpp kpdf/ui/pageview.cpp
+*** kpdf.orig/ui/pageview.cpp 2007-11-13 09:43:02.000000000 -0500
+--- kpdf/ui/pageview.cpp 2007-11-13 10:26:15.000000000 -0500
+***************
+*** 930,936 ****
+ {
+ d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+ if ( !d->mouseOnRect )
+! setCursor( KCursor::sizeAllCursor() );
+ }
+ break;
+
+--- 930,965 ----
+ {
+ d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+ if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->geometry().left(),
+! click.y() - pageItem->geometry().top(),
+! pageItem->width(),
+! pageItem->height()
+! );
+! if (clickChart.x() == QCOORD_MIN && clickChart.y() == QCOORD_MIN)
+! { // no anchors
+! setCursor( KCursor::sizeAllCursor() );
+! break;
+! }
+! setCursor( KCursor::crossCursor() );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ break;
+
+***************
+*** 1005,1010 ****
+--- 1034,1045 ----
+ // handle click over a link
+ const KPDFLink * link = static_cast< const KPDFLink * >( linkRect->pointer() );
+ d->document->processLink( link );
++ if ( link->linkType() == KPDFLink::Browse )
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ const KPDFLinkBrowse * browse = static_cast< const KPDFLinkBrowse * >( link );
++ if ( browse->url().startsWith( "coord:", false ) )
++ setCursor( KCursor::crossCursor() );
++ }
+ }
+ else
+ {
+Only in kpdf/ui: pageview.cpp.orig
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.9.patch b/Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.9.patch
new file mode 100644
index 00000000000..ab20eaafa22
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/kpdf-3.5.9.patch
@@ -0,0 +1,291 @@
+diff -cr kpdf.orig/core/document.cpp kpdf/core/document.cpp
+*** kpdf.orig/core/document.cpp 2008-03-03 23:36:42.000000000 -0500
+--- kpdf/core/document.cpp 2008-03-03 23:36:59.000000000 -0500
+***************
+*** 26,31 ****
+--- 26,32 ----
+ #include <kuserprofile.h>
+ #include <krun.h>
+ #include <kstandarddirs.h>
++ #include <qclipboard.h>
+
+ // local includes
+ #include "document.h"
+***************
+*** 1066,1071 ****
+--- 1067,1082 ----
+
+ case KPDFLink::Browse: {
+ const KPDFLinkBrowse * browse = static_cast< const KPDFLinkBrowse * >( link );
++ if ( browse->url().startsWith( "coord:", false ) )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith( "anchor:", false ) ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+ if ( browse->url().startsWith( "mailto:", false ) )
+ kapp->invokeMailer( browse->url() );
+diff -cr kpdf.orig/core/page.cpp kpdf/core/page.cpp
+*** kpdf.orig/core/page.cpp 2008-03-03 23:36:42.000000000 -0500
+--- kpdf/core/page.cpp 2008-03-03 23:36:59.000000000 -0500
+***************
+*** 13,24 ****
+--- 13,27 ----
+ #include <qmap.h>
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "page.h"
+ #include "pagetransition.h"
+ #include "link.h"
+ #include "conf/settings.h"
+ #include "xpdf/TextOutputDev.h"
++ #include <stdlib.h>
+
+
+ /** class KPDFPage **/
+***************
+*** 172,177 ****
+--- 175,269 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint KPDFPage::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which kpdf has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by kpdf
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint();
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QValueList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Link)
++ {
++ const KPDFLink * link = static_cast< const KPDFLink * >( (*it)->pointer() );
++ if (link)
++ {
++ const KPDFLinkBrowse * browse = dynamic_cast< const KPDFLinkBrowse * >( link );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:", false) )
++ {
++ int comma;
++ QString xs;
++ NormalizedRect * r = (*it);
++ QRect unnormalized;
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.find(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ unnormalized = r->geometry(widthPage, heightPage);
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(QCOORD_MIN, QCOORD_MIN);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
+ const KPDFPageTransition * KPDFPage::getTransition() const
+ {
+ return m_transition;
+diff -cr kpdf.orig/core/page.h kpdf/core/page.h
+*** kpdf.orig/core/page.h 2008-03-03 23:36:42.000000000 -0500
+--- kpdf/core/page.h 2008-03-03 23:36:59.000000000 -0500
+***************
+*** 120,125 ****
+--- 120,128 ----
+ void deletePixmapsAndRects();
+ void deleteHighlights( int s_id = -1 );
+
++ // computes the factor that scales from pixel coordinates to chart coordinates:
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
+ private:
+ friend class PagePainter;
+ int m_number, m_rotation;
+diff -cr kpdf.orig/shell/main.cpp kpdf/shell/main.cpp
+*** kpdf.orig/shell/main.cpp 2008-03-03 23:36:42.000000000 -0500
+--- kpdf/shell/main.cpp 2008-03-03 23:36:59.000000000 -0500
+***************
+*** 19,25 ****
+ #include <klocale.h>
+
+ static const char description[] =
+! I18N_NOOP("kpdf, a kde pdf viewer based on xpdf");
+
+ static const char version[] = "0.5.9";
+
+--- 19,25 ----
+ #include <klocale.h>
+
+ static const char description[] =
+! I18N_NOOP("prerex-enabled kpdf, a kde pdf viewer based on xpdf for use with the prerex editor");
+
+ static const char version[] = "0.5.9";
+
+Only in kpdf/shell: main.cpp.orig
+diff -cr kpdf.orig/shell/shell.cpp kpdf/shell/shell.cpp
+*** kpdf.orig/shell/shell.cpp 2008-03-03 23:36:42.000000000 -0500
+--- kpdf/shell/shell.cpp 2008-03-03 23:36:59.000000000 -0500
+***************
+*** 34,39 ****
+--- 34,40 ----
+ #include <kparts/componentfactory.h>
+ #include <kio/netaccess.h>
+ #include <kmainwindowiface.h>
++ #include <kstatusbar.h>
+
+ // local includes
+ #include "shell.h"
+***************
+*** 75,81 ****
+--- 76,86 ----
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+ setupGUI(Keys | Save);
++ createStandardStatusBarAction();
++ setupGUI(ToolBar | Keys | Save | StatusBar );
+ createGUI(m_part);
++ m_statusBar = statusBar();
++ m_statusBar->message("This is prerex-enabled kpdf.", 8000);
+ m_showToolBarAction = static_cast<KToggleAction*>(toolBarMenuAction());
+ }
+ }
+diff -cr kpdf.orig/shell/shell.h kpdf/shell/shell.h
+*** kpdf.orig/shell/shell.h 2008-03-03 23:36:42.000000000 -0500
+--- kpdf/shell/shell.h 2008-03-03 23:36:59.000000000 -0500
+***************
+*** 103,108 ****
+--- 103,109 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KURL m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ }
+diff -cr kpdf.orig/ui/pageview.cpp kpdf/ui/pageview.cpp
+*** kpdf.orig/ui/pageview.cpp 2008-03-03 23:36:42.000000000 -0500
+--- kpdf/ui/pageview.cpp 2008-03-03 23:36:59.000000000 -0500
+***************
+*** 930,936 ****
+ {
+ d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+ if ( !d->mouseOnRect )
+! setCursor( KCursor::sizeAllCursor() );
+ }
+ break;
+
+--- 930,965 ----
+ {
+ d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+ if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->geometry().left(),
+! click.y() - pageItem->geometry().top(),
+! pageItem->width(),
+! pageItem->height()
+! );
+! if (clickChart.x() == QCOORD_MIN && clickChart.y() == QCOORD_MIN)
+! { // no anchors
+! setCursor( KCursor::sizeAllCursor() );
+! break;
+! }
+! setCursor( KCursor::crossCursor() );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ break;
+
+***************
+*** 1005,1010 ****
+--- 1034,1045 ----
+ // handle click over a link
+ const KPDFLink * link = static_cast< const KPDFLink * >( linkRect->pointer() );
+ d->document->processLink( link );
++ if ( link->linkType() == KPDFLink::Browse )
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ const KPDFLinkBrowse * browse = static_cast< const KPDFLinkBrowse * >( link );
++ if ( browse->url().startsWith( "coord:", false ) )
++ setCursor( KCursor::crossCursor() );
++ }
+ }
+ else
+ {
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.0.3.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.0.3.patch
new file mode 100644
index 00000000000..f76ebcfae83
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.0.3.patch
@@ -0,0 +1,332 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2008-05-19 11:32:40.000000000 -0400
+--- okular/aboutdata.h 2008-05-19 16:26:06.000000000 -0400
+***************
+*** 21,31 ****
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("okular, a universal document viewer"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Albert Astals Cid, Enrico Ros\n"
+! "(C) 2005 Piotr Szymanski"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 21,32 ----
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("okular, a universal document viewer (prerex-enabled version)"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Albert Astals Cid, Enrico Ros\n"
+! "(C) 2005 Piotr Szymanski\n"
+! "(C) 2006-2008 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 35,40 ****
+--- 36,42 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+
+ return about;
+ }
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2008-05-19 11:32:40.000000000 -0400
+--- okular/core/document.cpp 2008-05-19 11:33:05.000000000 -0400
+***************
+*** 44,49 ****
+--- 44,51 ----
+ #include <ktemporaryfile.h>
+ #include <ktoolinvocation.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2398,2405 ****
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+--- 2400,2417 ----
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( QString("mailto:"), Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2008-05-19 11:32:40.000000000 -0400
+--- okular/core/page.cpp 2008-05-19 11:33:05.000000000 -0400
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #ifdef PAGE_PROFILE
+ #include <QtCore/QTime>
+***************
+*** 336,341 ****
+--- 339,432 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2008-05-19 11:32:40.000000000 -0400
+--- okular/core/page.h 2008-05-19 11:33:05.000000000 -0400
+***************
+*** 298,303 ****
+--- 298,308 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2008-05-19 11:32:40.000000000 -0400
+--- okular/shell/shell.cpp 2008-05-19 16:12:28.000000000 -0400
+***************
+*** 42,47 ****
+--- 42,49 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+
+***************
+*** 77,83 ****
+--- 79,88 ----
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+ setupGUI(Keys | Save);
++ createStandardStatusBarAction();
+ createGUI(m_part);
++ m_statusBar = statusBar();
++ m_statusBar->showMessage("This is prerex-enabled okular.");
+ m_showToolBarAction = static_cast<KToggleAction*>(toolBarMenuAction());
+ m_doc = qobject_cast<KDocumentViewer*>(m_part);
+ }
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2008-05-19 11:32:40.000000000 -0400
+--- okular/shell/shell.h 2008-05-19 15:40:58.000000000 -0400
+***************
+*** 101,106 ****
+--- 101,107 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2008-05-19 11:32:40.000000000 -0400
+--- okular/ui/pageview.cpp 2008-05-19 11:33:05.000000000 -0400
+***************
+*** 1489,1497 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1489,1526 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->geometry().left(),
+! click.y() - pageItem->geometry().top(),
+! pageItem->width(),
+! pageItem->height()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1613,1618 ****
+--- 1642,1657 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else
+ {
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.0.4.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.0.4.patch
new file mode 100644
index 00000000000..76e432be262
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.0.4.patch
@@ -0,0 +1,332 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2008-05-21 07:46:19.000000000 -0400
+--- okular/aboutdata.h 2008-05-21 07:46:42.000000000 -0400
+***************
+*** 21,31 ****
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("okular, a universal document viewer"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Albert Astals Cid, Enrico Ros\n"
+! "(C) 2005 Piotr Szymanski"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 21,32 ----
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("okular, a universal document viewer (prerex-enabled version)"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Albert Astals Cid, Enrico Ros\n"
+! "(C) 2005 Piotr Szymanski\n"
+! "(C) 2006-2008 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 35,40 ****
+--- 36,42 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+
+ return about;
+ }
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2008-05-21 07:46:19.000000000 -0400
+--- okular/core/document.cpp 2008-05-21 07:46:42.000000000 -0400
+***************
+*** 44,49 ****
+--- 44,51 ----
+ #include <ktemporaryfile.h>
+ #include <ktoolinvocation.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2405,2412 ****
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+--- 2407,2424 ----
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( QString("mailto:"), Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2008-05-21 07:46:19.000000000 -0400
+--- okular/core/page.cpp 2008-05-21 07:46:42.000000000 -0400
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #ifdef PAGE_PROFILE
+ #include <QtCore/QTime>
+***************
+*** 336,341 ****
+--- 339,432 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2008-05-21 07:46:19.000000000 -0400
+--- okular/core/page.h 2008-05-21 07:46:42.000000000 -0400
+***************
+*** 298,303 ****
+--- 298,308 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2008-05-21 07:46:19.000000000 -0400
+--- okular/shell/shell.cpp 2008-05-21 07:46:42.000000000 -0400
+***************
+*** 42,47 ****
+--- 42,49 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+
+***************
+*** 77,83 ****
+--- 79,88 ----
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+ setupGUI(Keys | Save);
++ createStandardStatusBarAction();
+ createGUI(m_part);
++ m_statusBar = statusBar();
++ m_statusBar->showMessage("This is prerex-enabled okular.");
+ m_showToolBarAction = static_cast<KToggleAction*>(toolBarMenuAction());
+ m_doc = qobject_cast<KDocumentViewer*>(m_part);
+ }
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2008-05-21 07:46:19.000000000 -0400
+--- okular/shell/shell.h 2008-05-21 07:46:42.000000000 -0400
+***************
+*** 101,106 ****
+--- 101,107 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2008-05-21 07:46:19.000000000 -0400
+--- okular/ui/pageview.cpp 2008-05-21 07:46:42.000000000 -0400
+***************
+*** 1489,1497 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1489,1526 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->geometry().left(),
+! click.y() - pageItem->geometry().top(),
+! pageItem->width(),
+! pageItem->height()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1613,1618 ****
+--- 1642,1657 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else
+ {
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.0.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.0.patch
new file mode 100644
index 00000000000..ac0e3593408
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.0.patch
@@ -0,0 +1,341 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2008-09-10 11:05:45.000000000 -0400
+--- okular/aboutdata.h 2008-09-10 11:19:49.000000000 -0400
+***************
+*** 21,33 ****
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 21,34 ----
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer (prerex-enabled version)"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano\n"
+! "(C) 2006-2008 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 37,42 ****
+--- 38,44 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created Okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+
+ return about;
+ }
+Only in okular: aboutdata.h.orig
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2008-09-10 11:05:45.000000000 -0400
+--- okular/core/document.cpp 2008-09-10 11:19:49.000000000 -0400
+***************
+*** 44,49 ****
+--- 44,51 ----
+ #include <ktemporaryfile.h>
+ #include <ktoolinvocation.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2735,2742 ****
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+--- 2737,2754 ----
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( QString("mailto:"), Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+Only in okular/core: document.cpp.orig
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2008-09-10 11:05:45.000000000 -0400
+--- okular/core/page.cpp 2008-09-10 11:19:49.000000000 -0400
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #ifdef PAGE_PROFILE
+ #include <QtCore/QTime>
+***************
+*** 360,365 ****
+--- 363,456 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+Only in okular/core: page.cpp.orig
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2008-09-10 11:05:45.000000000 -0400
+--- okular/core/page.h 2008-09-10 11:19:49.000000000 -0400
+***************
+*** 326,331 ****
+--- 326,336 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+Only in okular/core: page.h.orig
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2008-09-10 11:05:45.000000000 -0400
+--- okular/shell/shell.cpp 2008-09-10 11:19:49.000000000 -0400
+***************
+*** 42,47 ****
+--- 42,49 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+
+***************
+*** 77,83 ****
+--- 79,88 ----
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+ setupGUI(Keys | Save);
++ createStandardStatusBarAction();
+ createGUI(m_part);
++ m_statusBar = statusBar();
++ m_statusBar->showMessage("This is prerex-enabled okular.");
+ m_showToolBarAction = static_cast<KToggleAction*>(toolBarMenuAction());
+ m_doc = qobject_cast<KDocumentViewer*>(m_part);
+ }
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2008-09-10 11:05:45.000000000 -0400
+--- okular/shell/shell.h 2008-09-10 11:19:49.000000000 -0400
+***************
+*** 101,106 ****
+--- 101,107 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2008-09-10 11:05:45.000000000 -0400
+--- okular/ui/pageview.cpp 2008-09-10 12:19:02.000000000 -0400
+***************
+*** 1634,1642 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1634,1671 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->croppedGeometry().left(),
+! click.y() - pageItem->croppedGeometry().top(),
+! pageItem->croppedWidth(),
+! pageItem->croppedHeight()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1758,1763 ****
+--- 1787,1802 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else
+ {
+Only in okular/ui: pageview.cpp.orig
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.1.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.1.patch
new file mode 100644
index 00000000000..8e74f338a59
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.1.patch
@@ -0,0 +1,341 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2008-09-25 09:41:04.000000000 -0400
+--- okular/aboutdata.h 2008-09-25 09:42:30.000000000 -0400
+***************
+*** 21,33 ****
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 21,34 ----
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer (prerex-enabled version)"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano\n"
+! "(C) 2006-2008 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 37,42 ****
+--- 38,44 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created Okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+
+ return about;
+ }
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2008-09-25 09:41:04.000000000 -0400
+--- okular/core/document.cpp 2008-09-25 09:42:30.000000000 -0400
+***************
+*** 44,49 ****
+--- 44,51 ----
+ #include <ktemporaryfile.h>
+ #include <ktoolinvocation.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2739,2746 ****
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+--- 2741,2758 ----
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( QString("mailto:"), Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+Only in okular/core: document.cpp.orig
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2008-09-25 09:41:04.000000000 -0400
+--- okular/core/page.cpp 2008-09-25 09:42:30.000000000 -0400
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #ifdef PAGE_PROFILE
+ #include <QtCore/QTime>
+***************
+*** 360,365 ****
+--- 363,456 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2008-09-25 09:41:04.000000000 -0400
+--- okular/core/page.h 2008-09-25 09:42:30.000000000 -0400
+***************
+*** 326,331 ****
+--- 326,336 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+Only in okular: okular-4.1.1.patch
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2008-09-25 09:41:04.000000000 -0400
+--- okular/shell/shell.cpp 2008-09-25 09:53:00.000000000 -0400
+***************
+*** 42,47 ****
+--- 42,49 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+
+***************
+*** 77,83 ****
+--- 79,88 ----
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+ createGUI(m_part);
++ m_statusBar = statusBar();
++ m_statusBar->showMessage("This is prerex-enabled okular.");
+ setupGUI(Keys | Save);
++ createStandardStatusBarAction();
+ m_showToolBarAction = static_cast<KToggleAction*>(toolBarMenuAction());
+ m_doc = qobject_cast<KDocumentViewer*>(m_part);
+ }
+Only in okular/shell: shell.cpp.orig
+Only in okular/shell: shell.cpp.rej
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2008-09-25 09:41:04.000000000 -0400
+--- okular/shell/shell.h 2008-09-25 09:42:30.000000000 -0400
+***************
+*** 101,106 ****
+--- 101,107 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2008-09-25 09:41:04.000000000 -0400
+--- okular/ui/pageview.cpp 2008-09-25 09:42:30.000000000 -0400
+***************
+*** 1643,1651 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1643,1680 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->croppedGeometry().left(),
+! click.y() - pageItem->croppedGeometry().top(),
+! pageItem->croppedWidth(),
+! pageItem->croppedHeight()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1767,1772 ****
+--- 1796,1811 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else
+ {
+Only in okular/ui: pageview.cpp.orig
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.2.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.2.patch
new file mode 100644
index 00000000000..49eb1cfc102
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.2.patch
@@ -0,0 +1,326 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2008-10-21 13:53:48.000000000 -0400
+--- okular/aboutdata.h 2008-10-21 13:55:13.000000000 -0400
+***************
+*** 21,33 ****
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 21,34 ----
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer (prerex-enabled version)"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano\n"
+! "(C) 2006-2008 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 37,42 ****
+--- 38,44 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created Okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+
+ return about;
+ }
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2008-10-21 13:53:48.000000000 -0400
+--- okular/core/document.cpp 2008-10-21 13:55:13.000000000 -0400
+***************
+*** 44,49 ****
+--- 44,51 ----
+ #include <ktemporaryfile.h>
+ #include <ktoolinvocation.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2740,2747 ****
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+--- 2742,2759 ----
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( QString("mailto:"), Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+Only in okular/core: document.cpp.orig
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2008-10-21 13:53:48.000000000 -0400
+--- okular/core/page.cpp 2008-10-21 13:55:13.000000000 -0400
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #ifdef PAGE_PROFILE
+ #include <QtCore/QTime>
+***************
+*** 360,365 ****
+--- 363,456 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2008-10-21 13:53:48.000000000 -0400
+--- okular/core/page.h 2008-10-21 13:55:13.000000000 -0400
+***************
+*** 326,331 ****
+--- 326,336 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2008-10-21 13:53:48.000000000 -0400
+--- okular/shell/shell.cpp 2008-10-21 13:57:38.000000000 -0400
+***************
+*** 42,47 ****
+--- 42,49 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+
+Only in okular/shell: shell.cpp.orig
+Only in okular/shell: shell.cpp.rej
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2008-10-21 13:53:48.000000000 -0400
+--- okular/shell/shell.h 2008-10-21 13:55:13.000000000 -0400
+***************
+*** 101,106 ****
+--- 101,107 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2008-10-21 13:53:48.000000000 -0400
+--- okular/ui/pageview.cpp 2008-10-21 13:55:13.000000000 -0400
+***************
+*** 1643,1651 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1643,1680 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->croppedGeometry().left(),
+! click.y() - pageItem->croppedGeometry().top(),
+! pageItem->croppedWidth(),
+! pageItem->croppedHeight()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1767,1772 ****
+--- 1796,1811 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else
+ {
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.3.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.3.patch
new file mode 100644
index 00000000000..46a2dd2d060
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.3.patch
@@ -0,0 +1,323 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2008-11-30 15:27:36.000000000 -0500
+--- okular/aboutdata.h 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 21,33 ****
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 21,34 ----
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer (prerex-enabled version)"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano\n"
+! "(C) 2006-2008 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 37,42 ****
+--- 38,44 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created Okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+
+ return about;
+ }
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2008-11-30 15:27:36.000000000 -0500
+--- okular/core/document.cpp 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 44,49 ****
+--- 44,51 ----
+ #include <ktemporaryfile.h>
+ #include <ktoolinvocation.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2740,2747 ****
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+--- 2742,2759 ----
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( QString("mailto:"), Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2008-11-30 15:27:36.000000000 -0500
+--- okular/core/page.cpp 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #ifdef PAGE_PROFILE
+ #include <QtCore/QTime>
+***************
+*** 360,365 ****
+--- 363,456 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2008-11-30 15:27:36.000000000 -0500
+--- okular/core/page.h 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 326,331 ****
+--- 326,336 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2008-11-30 15:27:36.000000000 -0500
+--- okular/shell/shell.cpp 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 41,46 ****
+--- 41,48 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2008-11-30 15:27:36.000000000 -0500
+--- okular/shell/shell.h 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 99,104 ****
+--- 99,105 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2008-11-30 15:27:36.000000000 -0500
+--- okular/ui/pageview.cpp 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 1653,1661 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1653,1690 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->croppedGeometry().left(),
+! click.y() - pageItem->croppedGeometry().top(),
+! pageItem->croppedWidth(),
+! pageItem->croppedHeight()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1777,1782 ****
+--- 1806,1821 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else
+ {
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.4.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.4.patch
new file mode 100644
index 00000000000..46a2dd2d060
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.1.4.patch
@@ -0,0 +1,323 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2008-11-30 15:27:36.000000000 -0500
+--- okular/aboutdata.h 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 21,33 ****
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 21,34 ----
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer (prerex-enabled version)"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano\n"
+! "(C) 2006-2008 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 37,42 ****
+--- 38,44 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created Okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+
+ return about;
+ }
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2008-11-30 15:27:36.000000000 -0500
+--- okular/core/document.cpp 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 44,49 ****
+--- 44,51 ----
+ #include <ktemporaryfile.h>
+ #include <ktoolinvocation.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2740,2747 ****
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+--- 2742,2759 ----
+
+ case Action::Browse: {
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+! if ( browse->url().startsWith( QString("mailto:"), Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+ else
+ {
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2008-11-30 15:27:36.000000000 -0500
+--- okular/core/page.cpp 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #ifdef PAGE_PROFILE
+ #include <QtCore/QTime>
+***************
+*** 360,365 ****
+--- 363,456 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2008-11-30 15:27:36.000000000 -0500
+--- okular/core/page.h 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 326,331 ****
+--- 326,336 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2008-11-30 15:27:36.000000000 -0500
+--- okular/shell/shell.cpp 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 41,46 ****
+--- 41,48 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2008-11-30 15:27:36.000000000 -0500
+--- okular/shell/shell.h 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 99,104 ****
+--- 99,105 ----
+ KToggleAction* m_showToolBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2008-11-30 15:27:36.000000000 -0500
+--- okular/ui/pageview.cpp 2008-11-30 15:28:25.000000000 -0500
+***************
+*** 1653,1661 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1653,1690 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->croppedGeometry().left(),
+! click.y() - pageItem->croppedGeometry().top(),
+! pageItem->croppedWidth(),
+! pageItem->croppedHeight()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1777,1782 ****
+--- 1806,1821 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else
+ {
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.2.0.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.2.0.patch
new file mode 100644
index 00000000000..386d9d20355
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.2.0.patch
@@ -0,0 +1,318 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2009-02-13 17:51:29.000000000 -0500
+--- okular/aboutdata.h 2009-02-13 17:51:55.000000000 -0500
+***************
+*** 21,33 ****
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 21,34 ----
+ "okular",
+ ki18n(iname), //I18N_NOOP("okular"),
+ OKULAR_VERSION_STRING,
+! ki18n("Okular, a universal document viewer (prerex-enabled version)"),
+ KAboutData::License_GPL,
+ ki18n("(C) 2002 Wilco Greven, Christophe Devriese\n"
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2008 Albert Astals Cid\n"
+! "(C) 2006-2008 Pino Toscano\n"
+! "(C) 2006-2008 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 37,42 ****
+--- 38,44 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created Okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+
+ return about;
+ }
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2009-02-13 17:51:29.000000000 -0500
+--- okular/core/document.cpp 2009-02-13 19:18:27.000000000 -0500
+***************
+*** 47,52 ****
+--- 47,54 ----
+ #include <ktoolinvocation.h>
+ #include <kzip.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2871,2876 ****
+--- 2873,2888 ----
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ QString lilySource;
+ int lilyRow = 0, lilyCol = 0;
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
+ // if the url is a mailto one, invoke mailer
+ if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+Only in okular/core: document.cpp.orig
+Only in okular/core: document.cpp.rej
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2009-02-13 17:51:29.000000000 -0500
+--- okular/core/page.cpp 2009-02-13 17:51:55.000000000 -0500
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #ifdef PAGE_PROFILE
+ #include <QtCore/QTime>
+***************
+*** 360,365 ****
+--- 363,456 ----
+ return 0;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2009-02-13 17:51:29.000000000 -0500
+--- okular/core/page.h 2009-02-13 17:51:55.000000000 -0500
+***************
+*** 326,331 ****
+--- 326,336 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2009-02-13 17:51:29.000000000 -0500
+--- okular/shell/shell.cpp 2009-02-13 17:51:55.000000000 -0500
+***************
+*** 43,48 ****
+--- 43,50 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+
+Only in okular/shell: shell.cpp.orig
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2009-02-13 17:51:29.000000000 -0500
+--- okular/shell/shell.h 2009-02-13 17:51:55.000000000 -0500
+***************
+*** 102,107 ****
+--- 102,108 ----
+ KToggleAction* m_showMenuBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+Only in okular/shell: shell.h.orig
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2009-02-13 17:51:29.000000000 -0500
+--- okular/ui/pageview.cpp 2009-02-13 17:51:55.000000000 -0500
+***************
+*** 1691,1699 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1691,1728 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->croppedGeometry().left(),
+! click.y() - pageItem->croppedGeometry().top(),
+! pageItem->croppedWidth(),
+! pageItem->croppedHeight()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1815,1820 ****
+--- 1844,1859 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else
+ {
+Only in okular/ui: pageview.cpp.orig
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.3.0.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.3.0.patch
new file mode 100644
index 00000000000..a7cfab47926
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.3.0.patch
@@ -0,0 +1,334 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2009-09-06 15:53:13.000000000 -0400
+--- okular/aboutdata.h 2009-09-06 15:58:31.000000000 -0400
+***************
+*** 27,33 ****
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2009 Albert Astals Cid\n"
+! "(C) 2006-2009 Pino Toscano"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 27,34 ----
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2009 Albert Astals Cid\n"
+! "(C) 2006-2009 Pino Toscano\n"
+! "(C) 2006-2009 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 37,42 ****
+--- 38,44 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created Okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+ about.addCredit(ki18n("Eugene Trounev"), ki18n("Annotations artwork"), "eugene.trounev@gmail.com");
+
+ return about;
+Only in okular: aboutdata.h.orig
+Only in okular: aboutdata.h.rej
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2009-09-06 15:53:13.000000000 -0400
+--- okular/core/document.cpp 2009-09-06 16:01:33.000000000 -0400
+***************
+*** 47,52 ****
+--- 47,54 ----
+ #include <ktoolinvocation.h>
+ #include <kzip.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2902,2907 ****
+--- 2904,2920 ----
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ QString lilySource;
+ int lilyRow = 0, lilyCol = 0;
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
++
+ // if the url is a mailto one, invoke mailer
+ if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+Only in okular/core: document.cpp.orig
+Only in okular/core: document.cpp.rej
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2009-09-06 15:53:13.000000000 -0400
+--- okular/core/page.cpp 2009-09-06 15:53:43.000000000 -0400
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #include <limits>
+
+***************
+*** 386,391 ****
+--- 389,482 ----
+ return res;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+Only in okular/core: page.cpp.orig
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2009-09-06 15:53:13.000000000 -0400
+--- okular/core/page.h 2009-09-06 15:53:43.000000000 -0400
+***************
+*** 333,338 ****
+--- 333,343 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+Only in okular/core: page.h.orig
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2009-09-06 15:53:13.000000000 -0400
+--- okular/shell/shell.cpp 2009-09-06 16:05:09.000000000 -0400
+***************
+*** 43,48 ****
+--- 43,50 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+
+***************
+*** 110,117 ****
+ // tell the KParts::MainWindow that this is indeed the main widget
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+- setupGUI(Keys | ToolBar | Save);
+ createGUI(m_part);
+ m_doc = qobject_cast<KDocumentViewer*>(m_part);
+ }
+
+--- 112,122 ----
+ // tell the KParts::MainWindow that this is indeed the main widget
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+ createGUI(m_part);
++ m_statusBar = statusBar();
++ m_statusBar->showMessage("This is prerex-enabled okular.");
++ setupGUI(Keys | ToolBar | Save);
++ createStandardStatusBarAction();
+ m_doc = qobject_cast<KDocumentViewer*>(m_part);
+ }
+
+Only in okular/shell: shell.cpp.orig
+Only in okular/shell: shell.cpp.rej
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2009-09-06 15:53:13.000000000 -0400
+--- okular/shell/shell.h 2009-09-06 15:53:43.000000000 -0400
+***************
+*** 102,107 ****
+--- 102,108 ----
+ KToggleAction* m_showMenuBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+Only in okular/shell: shell.h.orig
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2009-09-06 15:53:13.000000000 -0400
+--- okular/ui/pageview.cpp 2009-09-06 15:53:43.000000000 -0400
+***************
+*** 1696,1704 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1696,1733 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->croppedGeometry().left(),
+! click.y() - pageItem->croppedGeometry().top(),
+! pageItem->croppedWidth(),
+! pageItem->croppedHeight()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1820,1825 ****
+--- 1849,1864 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else if ( e->modifiers() == Qt::ShiftModifier )
+ {
+Only in okular/ui: pageview.cpp.orig
diff --git a/Master/texmf-dist/doc/latex/prerex/patches/okular-4.4.0.patch b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.4.0.patch
new file mode 100644
index 00000000000..94865529e95
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/patches/okular-4.4.0.patch
@@ -0,0 +1,329 @@
+diff -rc okular.orig/aboutdata.h okular/aboutdata.h
+*** okular.orig/aboutdata.h 2010-03-16 14:25:07.000000000 -0400
+--- okular/aboutdata.h 2010-03-16 14:25:50.000000000 -0400
+***************
+*** 27,33 ****
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2009 Albert Astals Cid\n"
+! "(C) 2006-2009 Pino Toscano"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+--- 27,34 ----
+ "(C) 2004-2005 Enrico Ros\n"
+ "(C) 2005 Piotr Szymanski\n"
+ "(C) 2004-2009 Albert Astals Cid\n"
+! "(C) 2006-2009 Pino Toscano\n"
+! "(C) 2006-2009 Bob Tennent"),
+ KLocalizedString(),
+ "http://okular.kde.org"
+ );
+***************
+*** 37,42 ****
+--- 38,44 ----
+ about.addAuthor(ki18n("Albert Astals Cid"), ki18n("Former maintainer"), "aacid@kde.org");
+ about.addAuthor(ki18n("Piotr Szymanski"), ki18n("Created Okular from KPDF codebase"), "djurban@pld-dc.org");
+ about.addAuthor(ki18n("Enrico Ros"), ki18n("KPDF developer"), "eros.kde@email.it");
++ about.addAuthor(ki18n("Bob Tennent"), ki18n("prerex developer"), "rdtennent@gmail.com");
+ about.addCredit(ki18n("Eugene Trounev"), ki18n("Annotations artwork"), "eugene.trounev@gmail.com");
+
+ return about;
+diff -rc okular.orig/core/document.cpp okular/core/document.cpp
+*** okular.orig/core/document.cpp 2010-03-16 14:25:07.000000000 -0400
+--- okular/core/document.cpp 2010-03-16 14:25:50.000000000 -0400
+***************
+*** 47,52 ****
+--- 47,54 ----
+ #include <ktoolinvocation.h>
+ #include <kzip.h>
+
++ #include <qclipboard.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 2955,2960 ****
+--- 2957,2973 ----
+ const BrowseAction * browse = static_cast< const BrowseAction * >( action );
+ QString lilySource;
+ int lilyRow = 0, lilyCol = 0;
++ if ( browse->url().startsWith( "coord:") )
++ { // for prerex: load coordinates of clicked box into the clipboard
++ QString message = browse->url();
++ QClipboard *cb = QApplication::clipboard();
++ message.remove("coord: ");
++ cb->setText(message, QClipboard::Selection );
++ }
++ else if ( browse->url().startsWith("anchor:") ) // ignore it
++ { }
++ else
++
+ // if the url is a mailto one, invoke mailer
+ if ( browse->url().startsWith( "mailto:", Qt::CaseInsensitive ) )
+ KToolInvocation::invokeMailer( browse->url() );
+Only in okular/core: document.cpp.orig
+diff -rc okular.orig/core/page.cpp okular/core/page.cpp
+*** okular.orig/core/page.cpp 2010-03-16 14:25:07.000000000 -0400
+--- okular/core/page.cpp 2010-03-16 14:25:50.000000000 -0400
+***************
+*** 20,25 ****
+--- 20,27 ----
+
+ #include <kdebug.h>
+
++ #include <kmessagebox.h>
++
+ // local includes
+ #include "action.h"
+ #include "annotations.h"
+***************
+*** 34,39 ****
+--- 36,42 ----
+ #include "rotationjob_p.h"
+ #include "textpage.h"
+ #include "textpage_p.h"
++ #include <stdlib.h>
+
+ #include <limits>
+
+***************
+*** 391,396 ****
+--- 394,487 ----
+ return res;
+ }
+
++ // computes the factor that scales from pixel coordinates to chart coordinates
++ const QPoint Page::scaleToChart (int xclick, int yclick, int widthPage, int heightPage) const
++ {
++ // Copyright (c) 2006 R. D. Tennent
++ // School of Computing, Queen's University, rdt@cs.queensu.ca
++ //
++ // There are *three* coordinate systems involved here:
++ //
++ // + chart coordinates, to which okular has no direct access
++ //
++ // + pixel coordinates, for example, as registered by a mouse click
++ //
++ // + normalized page coordinates in [0,1] range used internally
++ // by okular
++ //
++ // Implementation:
++ //
++ // Find the two "anchor: xci,yci" links, determine their
++ // "normalized" locations on the page, unnormalize to get the pixel
++ // coordinates (x1, y1) and (x2, y2) of their centre points, and
++ // then scale the mouse-click coordinates accordingly to get the
++ // corresponding chart coordinates (xc, yc).
++ //
++ QPoint clickChart = QPoint(); // what we're trying to determine
++ bool first = false, second = false;
++ int x1=0, y1=0, x2=0, y2=0; // pixel coordinates of centre points of two anchor links
++ int xc1=0, yc1=0, xc2=0, yc2=0; // chart coordinates of anchors, as determined by their URIs
++ int xc=0, yc=0; // rounded chart coordinates of mouse-click location
++
++ QLinkedList< ObjectRect * >::const_iterator it = m_rects.begin(), end = m_rects.end();
++ for ( ; it != end; ++it )
++ if ((*it)->objectType() == ObjectRect::Action)
++ {
++ const BrowseAction * action = static_cast< const BrowseAction * >( (*it)->object() );
++ if (action)
++ {
++ const BrowseAction * browse = dynamic_cast< const BrowseAction * >( action );
++ if (browse)
++ {
++ QString thisURL = browse->url();
++ if (thisURL.startsWith( "anchor:" ) )
++ {
++ int comma;
++ QString xs;
++ QRect unnormalized = (*it)->boundingRect(widthPage, heightPage);
++ thisURL.remove(0,7); // remove "anchor:"
++ comma = thisURL.indexOf(',');
++ xs = thisURL.left(comma); // x coordinate as a string
++ thisURL.remove(0, comma+1); // y coordinate as a string
++ if (!first)
++ {
++ QPoint p1; // centre of first anchor
++ xc1 = xs.toInt();
++ yc1 = thisURL.toInt();
++ p1 = unnormalized.center();
++ x1 = p1.x(); y1 = p1.y();
++ first = true;
++ }
++ else
++ {
++ QPoint p2; // centre of second anchor
++ xc2 = xs.toInt();
++ yc2 = thisURL.toInt();
++ p2 = unnormalized.center();
++ x2 = p2.x(); y2 = p2.y();
++ second = true;
++ break;
++ }
++ }
++ }
++ }
++ }
++ if (!second) return QPoint(-1, -1);
++ // KMessageBox::information(0, QString()
++ // + " x1= " + QString::number(x1)
++ // + " y1= " + QString::number(y1)
++ // + " x2= " + QString::number(x2)
++ // + " y2= " + QString::number(y1)
++ // + " xclick= " + QString::number(xclick)
++ // + " yclick= " + QString::number(yclick)
++ // );
++ xc = (int)( 0.25L + (xc1 + xc2)/2.0L - ((x1 + x2)/2.0L - xclick) * (xc2 - xc1) / (x2 - x1) ) ;
++ yc = (int)( 0.75L + (yc1 + yc2)/2.0L - ((y1 + y2)/2.0L - yclick) * (yc2 - yc1) / (y2 - y1) );
++ clickChart = QPoint(xc, yc);
++ return clickChart;
++ }
++
++
+ const PageTransition * Page::transition() const
+ {
+ return d->m_transition;
+Only in okular/core: page.cpp.orig
+diff -rc okular.orig/core/page.h okular/core/page.h
+*** okular.orig/core/page.h 2010-03-16 14:25:07.000000000 -0400
+--- okular/core/page.h 2010-03-16 14:25:50.000000000 -0400
+***************
+*** 340,345 ****
+--- 340,350 ----
+ */
+ void deleteAnnotations();
+
++ /** computes the factor that scales from pixel coordinates to chart coordinates:
++ */
++ const QPoint scaleToChart(int xclick, int yclick, int widthPage, int heightPage) const;
++
++
+ private:
+ PagePrivate* const d;
+ /// @cond PRIVATE
+Only in okular/core: page.h.orig
+diff -rc okular.orig/shell/shell.cpp okular/shell/shell.cpp
+*** okular.orig/shell/shell.cpp 2010-03-16 14:25:07.000000000 -0400
+--- okular/shell/shell.cpp 2010-03-16 14:25:50.000000000 -0400
+***************
+*** 43,48 ****
+--- 43,50 ----
+ #include <ktogglefullscreenaction.h>
+ #include <kactioncollection.h>
+
++ #include <kstatusbar.h>
++
+ // local includes
+ #include "kdocumentviewer.h"
+ #include "shellutils.h"
+***************
+*** 89,96 ****
+ // tell the KParts::MainWindow that this is indeed the main widget
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+- setupGUI(Keys | ToolBar | Save);
+ createGUI(m_part);
+ m_doc = qobject_cast<KDocumentViewer*>(m_part);
+ }
+
+--- 91,101 ----
+ // tell the KParts::MainWindow that this is indeed the main widget
+ setCentralWidget(m_part->widget());
+ // and integrate the part's GUI with the shell's
+ createGUI(m_part);
++ m_statusBar = statusBar();
++ m_statusBar->showMessage("This is prerex-enabled okular.");
++ setupGUI(Keys | ToolBar | Save);
++ createStandardStatusBarAction();
+ m_doc = qobject_cast<KDocumentViewer*>(m_part);
+ }
+
+Only in okular/shell: shell.cpp.orig
+diff -rc okular.orig/shell/shell.h okular/shell/shell.h
+*** okular.orig/shell/shell.h 2010-03-16 14:25:07.000000000 -0400
+--- okular/shell/shell.h 2010-03-16 14:25:50.000000000 -0400
+***************
+*** 102,107 ****
+--- 102,108 ----
+ KToggleAction* m_showMenuBarAction;
+ bool m_menuBarWasShown, m_toolBarWasShown;
+ KUrl m_openUrl;
++ KStatusBar *m_statusBar;
+ };
+
+ #endif
+diff -rc okular.orig/ui/pageview.cpp okular/ui/pageview.cpp
+*** okular.orig/ui/pageview.cpp 2010-03-16 14:25:07.000000000 -0400
+--- okular/ui/pageview.cpp 2010-03-16 14:25:50.000000000 -0400
+***************
+*** 1648,1656 ****
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! setCursor( Qt::SizeAllCursor );
+ }
+ }
+ else if ( rightButton )
+--- 1648,1685 ----
+ }
+ if ( !d->mouseAnn )
+ {
+! d->mouseGrabPos = d->mouseOnRect ? QPoint() : d->mousePressPos;
+! if ( !d->mouseOnRect )
+! {
+! QPoint click = QPoint(e->x(), e->y());
+! // need to compute chart coordinates from pixel coordinates
+! // first, find the relevant page:
+! PageViewItem * pageItem = pickItemOnPoint( click.x(), click.y() );
+! if ( pageItem )
+! { // load chart coordinates of clicked point into clipboard
+! QString message;
+! QClipboard *cb = QApplication::clipboard();
+! QPoint clickChart = pageItem->page()->
+! scaleToChart(
+! click.x() - pageItem->croppedGeometry().left(),
+! click.y() - pageItem->croppedGeometry().top(),
+! pageItem->croppedWidth(),
+! pageItem->croppedHeight()
+! );
+! if (clickChart.x() == -1 && clickChart.y() == -1)
+! { // no anchors
+! setCursor( Qt::SizeAllCursor );
+! break;
+! }
+! setCursor( Qt::CrossCursor );
+! message = "";
+! message.append(QString::number(clickChart.x()));
+! message.append(',');
+! message.append(QString::number(clickChart.y()));
+! // message = QString::number(pageItem->width());
+! cb->setText(message, QClipboard::Selection );
+! }
+! }
+ }
+ }
+ else if ( rightButton )
+***************
+*** 1774,1779 ****
+--- 1803,1818 ----
+ // handle click over a link
+ const Okular::Action * action = static_cast< const Okular::Action * >( rect->object() );
+ d->document->processAction( action );
++ if (action)
++ {
++ const Okular::BrowseAction * browse = static_cast< const Okular::BrowseAction * >( action );
++ if (browse)
++ { // for coord URIs with prerex, change cursor to cross to signal click success
++ QString thisURL = browse->url();
++ if ( thisURL.startsWith( "coord:" ) )
++ setCursor( Qt::CrossCursor );
++ }
++ }
+ }
+ else if ( e->modifiers() == Qt::ShiftModifier )
+ {
+Only in okular/ui: pageview.cpp.orig
diff --git a/Master/texmf-dist/doc/latex/prerex/prerex-6.0.1.tar.gz b/Master/texmf-dist/doc/latex/prerex/prerex-6.0.1.tar.gz
new file mode 100644
index 00000000000..60eb47dd37c
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/prerex-6.0.1.tar.gz
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/prerex/vprerex-6.0.tar.gz b/Master/texmf-dist/doc/latex/prerex/vprerex-6.0.tar.gz
new file mode 100644
index 00000000000..065701bdade
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/prerex/vprerex-6.0.tar.gz
Binary files differ
diff --git a/Master/texmf-dist/tex/latex/prerex/prerex.sty b/Master/texmf-dist/tex/latex/prerex/prerex.sty
new file mode 100644
index 00000000000..f868d548766
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/prerex/prerex.sty
@@ -0,0 +1,597 @@
+%% This is file 'prerex.sty'
+%%
+%% Copyright (C) 2006-10 R. D. Tennent, rdt@cs.queensu.ca
+%%
+%% 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 2003/12/01 or later.
+%%
+%% This work has the LPPL maintenance status "author-maintained".
+%
+% Instructions supported inside \begin{chart} ... \end{chart}:
+%
+% \[req]{half|full}course x,y: {course code}{course title}{timetable code}
+%
+% \mini x,y: {course code}
+%
+% solid arrow: \prereq x0,y0,x1,y1: \prereqc x0,y0,x1,y1;curvature:
+% dotted arrow: \coreq x0,y0,x1,y1: \coreqc x0,y0,x1,y1;curvature:
+% dashed arrow: \recomm x0,y0,x1,y1: \recommc x0,y0,x1,y1;curvature:
+%
+% \text x,y: {line of text}
+%
+% \grid coordinate grid background
+%
+% Stand-alone instructions (for explanatory notes):
+%
+% \solidarrow in-line solid arrow
+% \dottedarrow in-line dotted arrow
+% \dashedarrow in-line dashed arrow
+%
+% \lightbox in-line light course box
+% \boldbox in-line bold course box
+%
+% The following defaults are defined in prerex.sty (but may be re-defined by the user):
+%
+% \newcommand{\DefaultCurvature}{20}
+%
+% where the argument should be in the range 0-100; 0 means no curvature.
+%
+% \newcommand{\CourseURL}[3]{file:#3.html}
+%
+% where the arguments supplied at the call are the x and y coordinates
+% and the course code.
+%
+% \newcommand{\background}{yellow!15}
+%
+% \setlength{\unit}{5.7816pt} length of a coordinate unit; gives 10 pixels per unit at 125dpi
+% \newcommand{\dpi}{125}
+% \newcommand\PixelsPerUnit{10}
+% \setcounter{diagheight}{75} but reduced to 65 in landscape mode
+% \newcommand{\solidwidth}{0.5pt}
+% \newcommand{\dottedwidth}{0.8pt}
+% \newcommand{\dashedwidth}{0.5pt}
+% \newcommand{\boldwidth}{1.0pt}
+% \newcommand{\smallersize}{\relsize{-3}}
+%
+% The nominal diagram width is 10 + (\textwidth divided by \unit).
+%
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{prerex}[2010/06/25 v6.0 LaTeX style for prerequisite charts, pgf version]
+
+% Changelog:
+%
+% Version 6.0
+% Version 5.7
+%
+% added implementation details to documentation
+% generated script now only crops the chart image
+%
+% Version 5.6
+% Version 5.5
+%
+% version increased to keep pace with previewer/vprerex
+%
+% Version 5.4
+%
+% code clean-up
+%
+% Version 5.3
+%
+% produces an image-generating script in \jobname.sh
+%
+% Version 5.2
+%
+% use \grid and \foreach (tikz) instead of \multido
+% half-course boxes now have a minimum height (5 units) to improve uniformity
+%
+% Version 5.1
+%
+% generates image-map data in \jobname_n.html for nth chart when n>1
+%
+% Version 5.0
+%
+% also generates \jobname.html with image-map data for all node URLs
+% new configuration commands \dpi and \PixelsPerUnit
+% default \unit length adjusted to give 10 pixels per coordinate unit at 125 dpi
+%
+% Version 4.4
+%
+% increase ysep parameter to 1.8pt to separate course-code or text and arrow tails for minis
+% and text boxes
+%
+% Version 4.3
+%
+% introduce \smallersize configuration command
+%
+% Version 4.2
+%
+% using tinting with xcolor package to ease background-color changes
+%
+% Version 4.1
+%
+% Version 4.0
+%
+% Implement the \text command to place a line of text (centered at the coordinates) in a chart
+%
+% Version 3.8.1:
+%
+% adjust arraystretch factors to work with long-ascender fonts such as Futura
+% adjust inner sep parameters to work with oblique/italic fonts
+% remove workaround for pgf-1.10 bug described at
+% http://sourceforge.net/forum/forum.php?thread_id=1621660&forum_id=477363
+% require version 1.18 (or later) of pgf
+%
+% Version 3.8:
+%
+% require version 1.10 (or later) of pgf
+%
+% Version 3.7:
+%
+% anchor nodes must be non-null for latex/dvips
+%
+% Version 3.6:
+%
+% first pgf-based version
+%
+% Version 3.5:
+% Version 3.4:
+%
+% introduce arrow borders to improve the appearance of crossing arrows
+% change default widths to artifacts created when arrow borders
+% occlude box boundaries
+%
+% Version 3.3:
+%
+% arrows (as well as course boxes and minis) are hyperlinked with coordinate URIs
+%
+% Version 3.2:
+%
+% Version 3.1:
+%
+% Version 3.0:
+%
+% "anchor" hyperlinks are added to coordinate grid to allow computation of
+% chart coordinates at mouse clicks
+%
+% Version 2.0:
+%
+% CourseURL now takes 3 arguments
+% box/mini coordinates displayed in (some) PDF viewers when grid on
+%
+% Version 1.0.2:
+%
+% using \relsize{-3} rather than \scriptsize
+% using \textsf in \lightbox and \boldbox
+%
+% Version 1.0.1:
+%
+% using \RequirePackage rather than \usepackage (suggested by Herbert Voss)
+%
+
+\newlength{\unit}
+
+\setlength{\unit}{5.7816pt} % 10 pixels per unit at 125dpi; 1pt = (1/72.27) in.
+\newcommand{\PixelsPerUnit}{10}
+\newcommand{\dpi}{125}
+
+\RequirePackage{relsize}
+\RequirePackage{calc}
+\RequirePackage{pgf}[2007/06/12]
+\RequirePackage{tikz}\usetikzlibrary{arrows}
+\RequirePackage{ifthen}
+\RequirePackage{textcomp}
+\RequirePackage{zref-savepos}
+\PassOptionsToPackage{urlcolor=black,colorlinks}{hyperref}
+\RequirePackage{hyperref}
+
+\RequirePackage{xcolor}
+\definecolor{light}{gray}{0.5}
+\definecolor{somewhatlight}{gray}{0.7}
+\definecolor{verylight}{gray}{0.85}
+\definecolor{white}{rgb}{1.0,1.0,1.0} % not transparent, hides grid
+
+\newcommand{\DefaultCurvature}{20} % 0 for no curvature
+\newcommand{\CourseURL}[3]{file:#3.html}
+\newcommand{\background}{yellow!15}
+
+\newcommand{\solidwidth}{0.5pt}
+\newcommand{\boldwidth}{1.0pt}
+\newcommand{\dottedwidth}{0.8pt}
+\newcommand{\dashedwidth}{0.5pt}
+\newcommand{\smallersize}{\relsize{-3}}
+
+\newcounter{@myangle}
+\newcounter{@inangle}
+\newcounter{@dx}
+\newcounter{@dy}
+
+\newif\ifgridon
+\gridonfalse
+\newcounter{@gridwidth}
+\newcounter{@gridright}
+\newcounter{@gridheight}
+\newcounter{@gridtop}
+
+\newcounter{@diagwidth}
+\newcounter{diagheight}
+
+\setcounter{diagheight}{75}
+\ifdim\paperwidth>\paperheight
+ \setcounter{diagheight}{65}
+\fi
+
+\newcounter{chart} % in case there is more than one chart in the document
+\newcounter{xNW}\newcounter{yNW} % coordinates of NW corner of a node
+\newcounter{xSE}\newcounter{ySE} % coordinates of SE corner of a node
+
+\def\@unitmult{\unit * 5} % used for the grid and as the minimum height of half-course boxes
+
+\def\@outputImapData#1,#2:#3#4#5{%
+% #1,#2 coordinates
+% #3 URL
+% #4 horizontal delta
+% #5 vertical delta
+%
+\setcounter{xNW}{\dpi * \ratio{\zposx{gridOrigin_\thechart}sp}{1in}}% # of pixels from left edge to origin
+\addtocounter{xNW}{(#1-#4)*\PixelsPerUnit}% add # pixels from origin to node (-#4 units)
+\setcounter{xSE}{\dpi * \ratio{\zposx{gridOrigin_\thechart}sp}{1in}}%
+\addtocounter{xSE}{(#1+#4)*\PixelsPerUnit}% add # pixels from origin to node (+#4 units)
+
+\setcounter{yNW}{ \dpi * \ratio{\paperheight}{1in}} % # of pixels for the whole page
+\addtocounter{yNW}{ 0 - \dpi * \ratio{\zposy{gridOrigin_\thechart}sp}{1in}} % subtract # pixels from bottom edge to origin
+\addtocounter{yNW}{0 - (#2 - #5) * \PixelsPerUnit } % subtract # of pixels from origin to node (-#5)
+\setcounter{ySE}{ \dpi * \ratio{\paperheight}{1in}}
+\addtocounter{ySE}{0 - \dpi * \ratio{\zposy{gridOrigin_\thechart}sp}{1in}}
+\addtocounter{ySE}{0 - (#2 + #5) * \PixelsPerUnit } % subtract # of pixels from origin to node (+#5)
+
+\immediate\write\@imapfile{<area shape=rect coords="\thexNW,\theyNW,\thexSE,\theySE" href="\CourseURL{#1}{#2}{#3}" target="_new">}%
+}
+
+\def\@halfcourse#1,#2:#3#4#5{%
+\node[draw,thin,fill=\background,rounded corners=2pt,inner ysep=0.5pt,minimum height=\@unitmult](x#1y#2) at (#1,#2)%
+{\textsf{%
+\renewcommand{\arraystretch}{0.8}%
+\href{\CourseURL{#1}{#2}{#3}}{\begin{tabular}{@{\hspace{1pt}}c@{\hspace{1pt}}}%
+\mbox{\smallersize#3}\,\hfill\,\mbox{\smallersize#5}\\ #4%
+\end{tabular}}}%
+};%
+\@outputImapData#1,#2:{#3}{4}{2}%
+}
+
+\def\@reqhalfcourse#1,#2:#3#4#5{%
+\node[draw,line width=\boldwidth,fill=\background,rounded corners=2pt,inner ysep=0.5pt,minimum height=\@unitmult](x#1y#2) at (#1,#2)%
+{\textsf{\textbf{%
+\renewcommand{\arraystretch}{0.8}%
+\href{\CourseURL{#1}{#2}{#3}}{\begin{tabular}{@{\hspace{1pt}}c@{\hspace{1pt}}}%
+\mbox{\smallersize#3}\,\hfill\,\mbox{\smallersize#5}\\ #4%
+\end{tabular}}}%
+}};%
+\@outputImapData#1,#2:{#3}{4}{2}%
+}
+
+\def\@fullcourse#1,#2:#3#4#5{%
+\node[draw,thin,fill=\background,rounded corners=2pt,inner ysep=0.5pt](x#1y#2) at (#1,#2)%
+{\textsf{%
+\renewcommand{\arraystretch}{1.7}%
+\href{\CourseURL{#1}{#2}{#3}}{\begin{tabular}{@{\hspace{1pt}}c@{\hspace{1pt}}}%
+\mbox{\smallersize#3}\,\hfill\,\mbox{\smallersize#5}\\ #4%
+\end{tabular}}}%
+};%
+\@outputImapData#1,#2:{#3}{4}{5}%
+}
+
+
+\def\@reqfullcourse#1,#2:#3#4#5{%
+\node[draw,line width=\boldwidth,fill=\background,rounded corners=2pt,inner ysep=0.5pt](x#1y#2) at (#1,#2)%
+{\textsf{\textbf{%
+\renewcommand{\arraystretch}{1.7}%
+\href{\CourseURL{#1}{#2}{#3}}{\begin{tabular}{@{\hspace{1pt}}c@{\hspace{1pt}}}%
+\mbox{\smallersize#3}\,\hfill\,\mbox{\smallersize#5}\\ #4%
+\end{tabular}}}}%
+};%
+\@outputImapData#1,#2:{#3}{4}{5}%
+}
+
+
+\def\@mini#1,#2:#3{%
+\node[fill=white,draw=white,inner ysep=1.8pt](x#1y#2) at (#1,#2)%
+{\textsf{%
+\href{\CourseURL{#1}{#2}{#3}}{%
+\mbox{\smallersize#3}}}};%
+\@outputImapData#1,#2:{#3}{2}{1}%
+}
+
+\def\@text#1,#2:#3{%
+% include coordinates if grid on, but don't hyperlink if grid off
+\ifgridon
+ \node[fill=white,draw=white,inner ysep=1.8pt](x#1y#2) at (#1,#2)%
+{\href{coord: #1,#2}{\mbox{#3}}};%
+\else
+ \node[fill=white,draw=white,inner ysep=1.8pt](x#1y#2) at (#1,#2){\mbox{#3}};%
+\fi
+}
+
+\def\@prereq#1,#2,#3,#4:{%
+ \setcounter{@dy}{#2-#4}
+ \ifnum\the@dy<10
+ \@straight#1,#2,#3,#4:
+ \else\ifnum#1=#3
+ \@straight#1,#2,#3,#4:
+ \else\ifnum#2=#4
+ \@straight#1,#2,#3,#4:
+ \else
+ \@prereqc#1,#2,#3,#4;\DefaultCurvature:
+ \fi\fi\fi
+}
+
+\def\@prereqc#1,#2,#3,#4;#5:{%
+ \ifnum#5=0
+ \@straight#1,#2,#3,#4:
+ \else
+ \@curved#1,#2,#3,#4;#5:
+ \fi
+}
+
+\def\@recomm#1,#2,#3,#4:{%
+ \setcounter{@dy}{#2-#4}
+ \ifnum\the@dy<10
+ \@straightDashed#1,#2,#3,#4:
+ \else\ifnum#1=#3
+ \@straightDashed#1,#2,#3,#4:
+ \else\ifnum#2=#4
+ \@straightDashed#1,#2,#3,#4:
+ \else
+ \@recommc#1,#2,#3,#4;\DefaultCurvature:
+ \fi\fi\fi
+}
+
+\def\@recommc#1,#2,#3,#4;#5:{%
+ \ifnum#5=0
+ \@straightDashed#1,#2,#3,#4:
+ \else
+ \@curvedDashed#1,#2,#3,#4;#5:
+ \fi
+}
+
+\def\@coreq#1,#2,#3,#4:{%
+ \setcounter{@dy}{#2-#4}
+ \ifnum\the@dy<10
+ \@straightDotted#1,#2,#3,#4:
+ \else\ifnum#1=#3
+ \@straightDotted#1,#2,#3,#4:
+ \else\ifnum#2=#4
+ \@straightDotted#1,#2,#3,#4:
+ \else
+ \@coreqc#1,#2,#3,#4;\DefaultCurvature:
+ \fi\fi\fi
+}
+
+\def\@coreqc#1,#2,#3,#4;#5:{%
+ \ifnum#5=0
+ \@straightDotted#1,#2,#3,#4:
+ \else
+ \@curvedDotted#1,#2,#3,#4;#5:
+ \fi
+}
+
+
+
+\def\@straight#1,#2,#3,#4:{%
+\ifgridon
+ \draw[draw=white,line width=1.5pt](x#1y#2) -- (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}};
+\else
+ \draw[draw=white,line width=1.5pt](x#1y#2) -- (x#3y#4) ;
+\fi
+ \draw[-latex',draw=white,very thin](x#1y#2) -- (x#3y#4) ;
+ \draw[line width=\solidwidth](x#1y#2) -- (x#3y#4) ;
+}
+
+
+\def\@curved#1,#2,#3,#4;#5:{
+
+ \ifnum#3<#1
+ \setcounter{@dx}{#1-#3}
+ \setcounter{@myangle}{(-#5) * \the@dx * \the@dy * 2}
+ \else
+ \setcounter{@dx}{#3-#1}
+ \setcounter{@myangle}{#5 * \the@dx * \the@dy * 2}
+ \fi
+ \setcounter{@myangle}{\the@myangle / ((\the@dx + \the@dy) * (\the@dx + \the@dy))}
+ \setcounter{@inangle}{180 - \the@myangle}
+ \ifgridon
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}} ;
+ \else
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \fi
+ \draw[-latex',draw=white,very thin](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \draw[line width=\solidwidth](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+}
+
+\def\@straightDashed#1,#2,#3,#4:{%
+\ifgridon
+ \draw[draw=white,line width=1.5pt] (x#1y#2) -- (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}};
+\else
+ \draw[draw=white,line width=1.5pt] (x#1y#2) -- (x#3y#4);
+\fi
+\draw[-latex',draw=white,very thin] (x#1y#2) -- (x#3y#4);
+\draw[dashed,line width=\dashedwidth] (x#1y#2) -- (x#3y#4);
+}
+
+\def\@curvedDashed#1,#2,#3,#4;#5:{
+ \ifnum#3<#1
+ \setcounter{@dx}{#1-#3}
+ \setcounter{@myangle}{(-#5) * \the@dx * \the@dy * 2}
+ \else
+ \setcounter{@dx}{#3-#1}
+ \setcounter{@myangle}{#5 * \the@dx * \the@dy * 2}
+ \fi
+ \setcounter{@myangle}{\the@myangle / ((\the@dx + \the@dy) * (\the@dx + \the@dy))}
+ \setcounter{@inangle}{180 - \the@myangle}
+ \ifgridon
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}} ;
+ \else
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \fi
+ \draw[-latex',draw=white,very thin](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \draw[dashed,line width=\dashedwidth](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+}
+
+\def\@straightDotted#1,#2,#3,#4:{%
+\ifgridon
+ \draw[draw=white,line width=1.5pt] (x#1y#2) -- (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}};
+\else
+ \draw[draw=white,line width=1.5pt] (x#1y#2) -- (x#3y#4);
+\fi
+\draw[-latex',draw=white,very thin] (x#1y#2) -- (x#3y#4);
+\draw[loosely dotted,line width=\dottedwidth] (x#1y#2) -- (x#3y#4);
+}
+
+\def\@curvedDotted#1,#2,#3,#4;#5:{
+ \ifnum#3<#1
+ \setcounter{@dx}{#1-#3}
+ \setcounter{@myangle}{(-#5) * \the@dx * \the@dy * 2}
+ \else
+ \setcounter{@dx}{#3-#1}
+ \setcounter{@myangle}{#5 * \the@dx * \the@dy * 2}
+ \fi
+ \setcounter{@myangle}{\the@myangle / ((\the@dx + \the@dy) * (\the@dx + \the@dy))}
+ \setcounter{@inangle}{180 - \the@myangle}
+ \ifgridon
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) node[midway] {\href{coord: #1,#2,#3,#4}{\quad}} ;
+ \else
+ \draw[draw=white,line width=1.5pt](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \fi
+ \draw[-latex',draw=white,very thin](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+ \draw[loosely dotted,line width=\dottedwidth](x#1y#2) to[out=\the@myangle,in=\the@inangle,relative] (x#3y#4) ;
+}
+
+\def\solidarrow{%
+\tikz[x=\unit,y=\unit,baseline=-0.5ex]
+\draw[-latex',line width =\solidwidth] (0,0) -- (4,0);
+}
+
+\def\dottedarrow{%
+\tikz[x=\unit,y=\unit,baseline=-0.5ex]
+\draw[loosely dotted,line width=\dottedwidth,-latex'] (0,0) -- (4,0);
+}
+
+\def\dashedarrow{%
+\tikz[x=\unit,y=\unit,baseline=-0.5ex]
+\draw[dashed,line width=\dashedwidth,-latex'] (0,0) -- (4,0);
+}
+
+\def\lightbox{%
+\tikz[thin,baseline=-0.5ex]\node[draw,fill=\background,rounded corners=2pt,inner sep=1.5pt]
+{\textsf{light}};}
+
+\def\boldbox{%
+\tikz[baseline=-0.65ex]\node[draw,line width=\boldwidth,fill=\background,rounded corners=2pt,inner sep=1.8pt]
+{\textsf{\textbf{bold}}};}
+
+\def\@grid{
+ \gridontrue
+ \renewcommand{\CourseURL}[3]{coord: ##1,##2} % "coord:" makes it look like a URI
+
+ \draw[line width=0.3pt,draw=verylight] (0,0) grid [step=1] (\value{@gridright},\value{@gridtop});
+ \draw[line width=0.4pt,draw=somewhatlight] (0,0) grid [step=5] (\value{@gridright},\value{@gridtop});
+
+ \foreach \i in {0,10,...,\value{@gridright}}
+ \node at (\i,-4){\mbox{\textsf{\small \i}}};
+
+ \foreach \i in {0,10,...,\value{@gridtop}}
+ \node at (-5,\i){\mbox{\textsf{\small \i}}};
+
+ \foreach \i in {0,10,...,\value{@gridright}}
+ \node at (\i,\value{@gridtop}+4){\mbox{\textsf{\small \i}}};
+
+ \foreach \i in {0,10,...,\value{@gridtop}}
+ \node at (\value{@gridright}+5,\i){\mbox{\textsf{\small \i}}};
+
+ % anchors are to allow computation of coordinates from mouse clicks in kpdf/okular:
+ % latex/dvips requires non-null href box
+ \node at (-5,-4) {\href{anchor: -5,-4}{\kern1sp}};
+ \setcounter{@gridtop}{\value{@gridtop} + 4}
+ \setcounter{@gridright}{\value{@gridright} + 5}
+ \node at (\the@gridright,\the@gridtop) {\href{anchor: \the@gridright,\the@gridtop}{\kern1sp}};
+}
+
+%
+%
+% \begin{chart} ... \end{chart}
+%
+%
+
+\newenvironment{chart}
+{ \setcounter{@diagwidth}{10 + 1 * \ratio{\textwidth}{\unit}}
+
+ \newwrite\@imapfile % image-map data
+ \newwrite\@scriptfile % shell script to generate image file
+ \ifthenelse{\value{chart} = 0}
+ { \immediate\openout\@imapfile=\jobname.map
+ \immediate\write\@imapfile{<map name="\jobname">}
+ }
+ { \immediate\openout\@imapfile=\jobname_\thechart.map
+ \immediate\write\@imapfile{<map name="\jobname_\thechart">}
+ }
+
+ \let\halfcourse=\@halfcourse
+ \let\reqhalfcourse=\@reqhalfcourse
+ \let\fullcourse=\@fullcourse
+ \let\reqfullcourse=\@reqfullcourse
+ \let\mini=\@mini
+ \let\text=\@text
+ \let\prereq=\@prereq
+ \let\prereqc=\@prereqc
+ \let\coreq=\@coreq
+ \let\coreqc=\@coreqc
+ \let\recomm=\@recomm
+ \let\recommc=\@recommc
+ \let\grid=\@grid
+ \begin{tikzpicture}[x=\unit,y=\unit]
+ \tikzstyle{every rectangle node}=[inner xsep=1.8pt]
+ \setcounter{@gridwidth}{(\the@diagwidth-5) / 10}
+ \setcounter{@gridright}{10 * \value{@gridwidth}}
+ \setcounter{@gridheight}{\thediagheight / 10}
+ \setcounter{@gridtop}{10 * \value{@gridheight} }
+ \useasboundingbox (0,-2) rectangle (\value{@gridright},\value{@gridtop});
+ node at (0,0) {\kern1sp\zsavepos{gridOrigin_\thechart}};
+ % access absolute page coordinates of the origin using \zposx and \zposy
+}
+{
+ \end{tikzpicture}
+ \write\@imapfile{</map>}
+ \closeout\@imapfile
+ \zsavepos{EndOfChart_\thechart} % determine cropping coordinates
+ \ifdim\paperwidth<\paperheight
+ % portrait mode
+ \setcounter{xSE}{\dpi * \ratio{\zposx{EndOfChart_\thechart}sp}{1in}}%
+ \setcounter{ySE}{ \dpi * \ratio{\paperheight}{1in}}
+ \addtocounter{ySE}{0 - \dpi * \ratio{\zposy{EndOfChart_\thechart}sp}{1in}}
+ \addtocounter{ySE}{0 + 2 * \PixelsPerUnit } % bottom margin
+ \else
+ % landscape mode
+ \setcounter{xSE}{ \dpi * \ratio{\paperwidth}{1in}}
+ \addtocounter{xSE}{0 - \dpi * \ratio{\zposx{EndOfChart_\thechart}sp}{1in}}%
+ \addtocounter{xSE}{0 + 2 * \PixelsPerUnit } % bottom margin
+ \setcounter{ySE}{ \dpi * \ratio{\paperheight}{1in}}
+ \addtocounter{ySE}{ 0 - \dpi * \ratio{\zposy{EndOfChart_\thechart}sp}{1in}}
+ \fi
+ \edef\HasH{\expandafter\@gobble\string\#}
+ \ifthenelse{\value{chart} = 0}
+ { % generate a script to crop a chart image
+ \immediate\openout\@scriptfile=\jobname.sh
+ \immediate\write\@scriptfile{\HasH!/bin/sh}
+ % defer remaining output till cropping coordinates are available
+ \write\@scriptfile{mogrify -crop \thexSE x\theySE +0+0 \jobname.png}
+ \write\@scriptfile{exit 0}
+ \closeout\@scriptfile
+ }
+ { % more than one chart; unlikely a script would be usable
+ }
+ \stepcounter{chart}
+}