summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/scanpages
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/scanpages
Initial commit
Diffstat (limited to 'macros/latex/contrib/scanpages')
-rw-r--r--macros/latex/contrib/scanpages/README40
-rw-r--r--macros/latex/contrib/scanpages/doc/pic1.pdfbin0 -> 3699 bytes
-rw-r--r--macros/latex/contrib/scanpages/doc/pic2.pdfbin0 -> 4289 bytes
-rw-r--r--macros/latex/contrib/scanpages/doc/replicate.plist205
-rwxr-xr-xmacros/latex/contrib/scanpages/doc/replicate.py114
-rw-r--r--macros/latex/contrib/scanpages/doc/scanpages-doc.pdfbin0 -> 123764 bytes
-rw-r--r--macros/latex/contrib/scanpages/doc/scanpages-doc.tex196
-rw-r--r--macros/latex/contrib/scanpages/map/scanpages.map1
-rw-r--r--macros/latex/contrib/scanpages/tex/scanpages.sty177
-rw-r--r--macros/latex/contrib/scanpages/tex/uscanwipe.fd6
-rw-r--r--macros/latex/contrib/scanpages/tfm/scanwipe.tfmbin0 -> 148 bytes
-rw-r--r--macros/latex/contrib/scanpages/type1/scanwipe.pfbbin0 -> 2627 bytes
12 files changed, 739 insertions, 0 deletions
diff --git a/macros/latex/contrib/scanpages/README b/macros/latex/contrib/scanpages/README
new file mode 100644
index 0000000000..82cfb548d1
--- /dev/null
+++ b/macros/latex/contrib/scanpages/README
@@ -0,0 +1,40 @@
+LaTeX package scanpages
+#======================
+# Copyright 2014--2016 Michael Sharpe, msharpe at ucsd dot edu.
+ #
+ # This work may be distributed and/or modified under the
+ # conditions of the LaTeX Project Public License, either version 1.3
+ # of this license or (at your option) any later version.
+ # The latest version of this license is in
+ # http://www.latex-project.org/lppl.txt
+ # and version 1.3 or later is part of all distributions of LaTeX
+ # version 2005/12/01 or later.
+ #
+ # This work has the LPPL maintenance status `maintained'.
+ #
+ # The Current Maintainer of this work is Michael Sharpe.
+ #
+ # This work consists of the files scanpages.sty, replicate.py and replicate.plist.
+
+Current version: 1.05a, 2016/12/02
+
+Changes in version 1.05a
+Corrections/additions to documentation.
+
+Changes in version 1.05
+1. Corrected some misbehaviors in scanpages.sty and some misinformaion in scanpages-doc.
+2. Made a small font with just a square and circular shape to act as eraser-heads---used in new macros \whitesq, \whitecirc.
+
+Changes in version 1.04
+Added options to include the page number from the original scanned document. (Thanks to Gill Williamson for his very useful input on this feature.)
+
+Changes in version 1.03
+Corrected a number of issues in scanpages.sty and its documentation so that the package now works as documented.
+
+Changes in version 1.02
+Corrected documentation and modified the scripts to handle text documents using carriage return for end-of-line.
+
+Changes in version 1.01
+AppleScript modified to remove dependence on external library TSLib. It is now self-contained.
+
+The sty file package contains macros to assist in embellishing a scanned document from the pre-TeX era, correcting positioning, adding footnotes, hyperlinks, indexing and so on. The script files provide ways to reduce the labor in preparing a .tex file with the required flexibility. For details, consult scanpages-doc.pdf.
diff --git a/macros/latex/contrib/scanpages/doc/pic1.pdf b/macros/latex/contrib/scanpages/doc/pic1.pdf
new file mode 100644
index 0000000000..9e562d3eab
--- /dev/null
+++ b/macros/latex/contrib/scanpages/doc/pic1.pdf
Binary files differ
diff --git a/macros/latex/contrib/scanpages/doc/pic2.pdf b/macros/latex/contrib/scanpages/doc/pic2.pdf
new file mode 100644
index 0000000000..5c2cd17066
--- /dev/null
+++ b/macros/latex/contrib/scanpages/doc/pic2.pdf
Binary files differ
diff --git a/macros/latex/contrib/scanpages/doc/replicate.plist b/macros/latex/contrib/scanpages/doc/replicate.plist
new file mode 100644
index 0000000000..fa40293b5a
--- /dev/null
+++ b/macros/latex/contrib/scanpages/doc/replicate.plist
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>name</key>
+ <string>ROOT</string>
+ <key>submenu</key>
+ <array>
+ <dict>
+ <key>content</key>
+ <string>--applescript direct
+--Michael Sharpe, 20140424
+--This is free software, but Copyright (c) Michael Sharpe, 2014
+--and subject to the LATEX Project Public License.
+--This allows replication of a commented block of text as many times as specified, substituting
+--values for 'variables' in the process
+
+property trimitems : {" ", tab, linefeed, return}
+
+set lf to linefeed
+set cr to return
+set crlf to cr &amp; lf
+
+set oldtid to text item delimiters
+tell application "TeXShop" to set s to content of selection of document 1
+set tmp to (paragraphs of s)
+set text item delimiters to {lf}
+set s to (tmp as text)
+set text item delimiters to "%Repetitions="
+set tmp to (text items of s)
+set text item delimiters to oldtid
+if not ((count of tmp) = 2) then
+ display dialog "Bailing! The selection does not contain exactly one '%Repetitions='"
+ return
+end if
+set ss to (item 2 of tmp)
+set tmp2 to (paragraphs of ss)
+set numrep to (item 1 of tmp2) as integer
+--next get variable names
+set text item delimiters to {"%Variables="}
+set tmp to (text items of s)
+set text item delimiters to oldtid
+if not ((count of tmp) = 2) then
+ display dialog "Bailing! The selection does not contain exactly one '%Variables='"
+ return
+end if
+set ss to (item 2 of tmp)
+set tmp2 to (paragraphs of ss)
+set vbllst to (item 1 of tmp2) --like {nnn,0:1+1,1:3+-2}
+set vbllst2 to trim(vbllst)
+set vbllst3 to (text 2 thru -2 of vbllst2)
+set text item delimiters to {" , ", " ,", " ,", ","}
+set vbles to (text items of vbllst3) -- line {nnn,0:1+1,1:3+-2}
+--display dialog "vbles=" &amp; (vbles as text)
+set n to (count of vbles)
+set root to (item 1 of vbles)
+set vlst to {}
+set vinit to {}
+set vinc to {}
+set valt to {}
+set text item delimiters to {":", "+"}
+repeat with j from 2 to n
+ set x to (text items of (item j of vbles))
+ if not ((count of x) = 3) then
+ display dialog "Bad variable descriptor-- " &amp; item j of vbles
+ set text item delimiters to oldtid
+ return
+ end if
+ set end of vlst to (item 1 of x)
+ set nnn to 0
+ set hasp to 0
+ if (last character of (item 3 of x) = ")") then
+ set hasp to 1
+ set nnn to ((text -2 of (item 3 of x)) as integer)
+ set (item 3 of x) to (text 1 thru -4 of (item 3 of x))
+ else
+ if (first character of (item 2 of x) = "[") then set nnn to -100
+ end if
+ if (item 3 of x) ends with "/2" then
+ set (item 3 of x) to (text 1 thru -3 of (item 3 of x))
+ if hasp = 1 then
+ set nnn to -nnn
+ else
+ set nnn to -10
+ end if
+ end if
+ set end of valt to nnn
+ if (nnn = -100) then
+ set end of vinit to (text 2 thru -1 of (item 2 of x))
+ set end of vinc to (text 1 thru -2 of (item 3 of x))
+ else
+ set end of vinit to (item 2 of x)
+ set end of vinc to (item 3 of x)
+ end if
+
+end repeat
+set text item delimiters to oldtid
+set viniti to {}
+set vinci to {}
+set kk to (count of vinit)
+repeat with j from 1 to kk
+ try
+ set end of viniti to ((item j of vinit) as integer)
+ on error
+ set end of viniti to 0
+ end try
+ try
+ set end of vinci to ((item j of vinc) as integer)
+ on error
+ set end of vinci to 0
+ end try
+end repeat
+set tmp to (paragraphs of s)
+set m to (count of tmp)
+set tmp2 to {}
+repeat with j from 3 to m
+ set t to (item j of tmp)
+ if ((count of t) &gt; 1) then
+ set t to (text 2 thru -1 of t)
+ else
+ set t to ""
+ end if
+ set end of tmp2 to t
+end repeat
+set text item delimiters to {lf}
+set body to (tmp2 as text)
+set text item delimiters to oldtid
+set repl to {s}
+set newbody to body
+repeat with p from 1 to numrep
+ set newbody to body
+ repeat with k from 1 to kk
+ set v to ""
+ set alt to (item k of valt)
+ if (alt = -100) then
+ if (p mod 2) = 0 then
+ set v to (item k of vinc)
+ else
+ set v to (item k of vinit)
+ end if
+ else
+ set v to (item k of viniti)
+ if (alt &lt; 0) then
+ set v to (v div 2)
+ set alt to -alt
+ end if
+ if (alt is not 10) and (alt is not 0) then
+ set v to zero_pad(v, alt)
+ else
+ set v to (v as string)
+ end if
+ end if
+ set newbody to switchText of newbody from (root &amp; (item k of vlst)) to v
+ set item k of viniti to (((item k of viniti) as integer) + (item k of vinci))
+ end repeat
+ set end of repl to newbody
+end repeat
+set text item delimiters to lf
+tell application "TeXShop" to set selection of document 1 to (repl as text)
+set AppleScript's text item delimiters to oldtid
+
+on zero_pad(value, string_length)
+ set tmp_string to "000000000" &amp; (value as string)
+ set padded_value to text ((count of tmp_string) - string_length + 1) thru -1 of tmp_string
+ return padded_value
+end zero_pad
+
+to switchText of t from s to r
+ set d to text item delimiters
+ set text item delimiters to s
+ set t to t's text items
+ set text item delimiters to r
+ tell t to set t to beginning &amp; ({""} &amp; rest)
+ set text item delimiters to d
+ t
+end switchText
+
+on trim(someText)
+ try
+ repeat until first character of someText is not in trimitems
+ set someText to text 2 thru -1 of someText
+ end repeat
+ on error
+ set someText to ""
+ end try
+
+ try
+ repeat until last character of someText is not in trimitems
+ set someText to text 1 thru -2 of someText
+ end repeat
+ on error
+ set someText to ""
+ end try
+ return someText
+end trim
+
+</string>
+ <key>key</key>
+ <string></string>
+ <key>name</key>
+ <string>Replicate</string>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/macros/latex/contrib/scanpages/doc/replicate.py b/macros/latex/contrib/scanpages/doc/replicate.py
new file mode 100755
index 0000000000..57a59782a7
--- /dev/null
+++ b/macros/latex/contrib/scanpages/doc/replicate.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+# Copyright (c) Michael Sharpe, 2014
+# This is free software, subject to the LATEX Project Public License.
+
+import sys
+
+filename=sys.argv[1]
+with open(filename,'r') as f:
+ tmp=f.read().splitlines()
+s='\n'.join(tmp)
+tmp=s.split("%Repetitions=")
+if len(tmp) != 2:
+ print "Bailing! The file does not contain exactly one '%Repetitions='"
+ sys.exit()
+ss=tmp[1]
+tmp2=ss.split('\n')
+numrep=int(tmp2[0])
+#get variable names
+tmp=s.split("%Variables=")
+if len(tmp) != 2:
+ print "Bailing! The file does not contain exactly one '%Variables='"
+ sys.exit()
+ss=tmp[1]
+tmp2=ss.split('\n')
+vbllst=tmp2[0].strip() #like {nnn,0:1+1,1:3+-2}
+vbllst3=vbllst[1:-1]
+vbles=vbllst3.split(',') #line {nnn,0:1+1,1:3+-2}
+n=len(vbles)
+root=vbles[0].strip()
+vlst=[]
+vinit=[]
+vinc=[]
+valt=[]
+for j in range(1,n):
+ vbles[j]=vbles[j].strip().replace("+",":")
+ x=vbles[j].split(":")
+ if len(x) != 3:
+ print "Bad variable descriptor-- " + vbles[j]
+ sys.exit
+ vlst.append(x[0])
+ nnn=0
+ hasp=0
+ if x[2][-1:] == ")":
+ hasp=1
+ nnn=int(x[2][-2])
+ x[2]=x[2][:-3]
+ else:
+ if x[1][0] == "[":
+ nnn=-100
+ if x[2][-2:]=="/2":
+ x[2]=x[2][:-2]
+ if hasp == 1:
+ nnn=-nnn
+ else:
+ nnn=-10
+ valt.append(nnn)
+ if nnn == -100:
+ vinit.append(x[1][1:])
+ vinc.append(x[2][:-1])
+ else:
+ vinit.append(x[1])
+ vinc.append(x[2])
+
+viniti=[]
+vinci=[]
+kk=len(vinit)
+for j in range(kk):
+ try:
+ viniti.append(int(vinit[j]))
+ except:
+ viniti.append(0)
+ try:
+ vinci.append(int(vinc[j]))
+ except:
+ vinci.append(0)
+tmp=s.split('\n')
+m=len(tmp)
+tmp2=[]
+for j in range(2,m):
+ t=tmp[j]
+ if len(t) > 1:
+ t=t[1:]
+ else:
+ t=""
+ tmp2.append(t)
+body='\n'.join(tmp2)
+repl=[s,]
+for p in range(numrep):
+ newbody=body
+ for k in range(kk):
+ v=""
+ alt=valt[k]
+ if alt == -100:
+ if (p % 2) == 1:
+ v=vinc[k]
+ else:
+ v=vinit[k]
+ else:
+ v=viniti[k]
+ if (alt < 0):
+ v=v//2
+ alt=-alt
+ if (alt!=10) and (alt!= 0):
+ v =str(v).zfill(alt)
+ else:
+ v=str(v)
+ newbody=newbody.replace(root+vlst[k],v)
+ viniti[k] =int(viniti[k]) + vinci[k]
+ repl.append(newbody)
+
+with open(filename,'w') as f:
+ for j in range(len(repl)):
+ f.write(repl[j]+'\n\n')
+
diff --git a/macros/latex/contrib/scanpages/doc/scanpages-doc.pdf b/macros/latex/contrib/scanpages/doc/scanpages-doc.pdf
new file mode 100644
index 0000000000..7f244f20a8
--- /dev/null
+++ b/macros/latex/contrib/scanpages/doc/scanpages-doc.pdf
Binary files differ
diff --git a/macros/latex/contrib/scanpages/doc/scanpages-doc.tex b/macros/latex/contrib/scanpages/doc/scanpages-doc.tex
new file mode 100644
index 0000000000..fd12b92605
--- /dev/null
+++ b/macros/latex/contrib/scanpages/doc/scanpages-doc.tex
@@ -0,0 +1,196 @@
+% !TEX TS-program = pdflatex
+\documentclass[11pt]{article}
+\usepackage[margin=1in]{geometry}
+\usepackage[parfill]{parskip}% Begin paragraphs with an empty line rather than an indent
+\usepackage{graphicx}
+%\pdfmapfile{+scanpages.map}
+%SetFonts
+% libertine+newtxmath
+\usepackage[osf,sups]{baskervillef}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+\usepackage[scaled=.85]{beramono}
+\usepackage[scaled=.95]{cabin}
+\usepackage{amsmath,amsthm}
+\usepackage[baskerville]{newtxmath}
+\usepackage{url}
+%SetFonts
+\usepackage{scanpages}
+\title{The \textsf{Scanpages} Package}
+\author{Michael Sharpe}
+\date{\today} % Activate to display a given date or no date
+
+\begin{document}
+\maketitle
+\section{Briefly}
+This package is intended for production of documents based on scanned material in any format acceptable to \textsf{pdflatex} as a graphic inclusion---eg, {\tt pdf}, {\tt png}, {\tt jpg}, though {\tt pdf} works best with this package. For me, the format has been useful when trying to archive pre-\TeX\ documents without converting them to \LaTeX\ source documents but inputting the scanned pages one by one and adding indexing, hyperlinks, a table of contents (You'll have to do this using \verb|\addcontentsline{toc}...|, and if using \textsf{hyperref}, you may need to add \verb|\phantomsection| immediately before \verb|\addcontentsline|), footnotes, marginal notes and the like. What makes scanned documents bothersome is the irregularities introduced by the scanning process. Pages are sometimes skewed and often offset horizontally and/or vertically from one another, and extraneous marks will likely appear, so each page may need adjustments. The methods of this package are of two types. First, the package {\tt scanpages.sty} contains macros to make it more convenient to perform those adjustments and add adornments. Second, some kind of script is very useful for making the relevant part of the {\tt tex} source, if you are handling more than a few pages of scanned material. For this, there are two almost equivalent scripts included to automate this process as much as possible, one written in \textsf{python}, the other in \textsf{AppleScript.} (The letter may be installed in \TeX Shop's macro menu for completely self-contained usage.)
+\section{The \LaTeX\ package}
+Starting with a scanned document, you need to measure four dimensions to specify the region you wish to import, and decide on a magnification factor to apply. The region to import from the scan should ideally be a bit larger (10{\tt pt} is a good starting value) than the area typically containing all the data, and perhaps excluding original page numbers. (The part of the scanned page lying outside the region is cropped.) The four critical dimensions are:
+\begin{itemize}
+\item
+The $x$ and $y$ coordinates {\tt llx, lly} of the lower left corner of the image region (the part you want to import) relative to the lower left corner of the scanned page;
+\item the width {\tt w} of the image region;
+\item the height {\tt h} of the image region.
+\end{itemize}
+The package is called using these items as options to the package.
+\begin{verbatim}
+\usepackage[scale=.9,llx=8cm,lly=12cm,w=3.5in,h=3.5in]{scanpages}
+\end{verbatim}
+It is not an error to omit one or more of these values, as default values will be substituted:
+\begin{itemize}
+\item
+{\tt llx} and {\tt lly} default to {\tt 1in}.
+\item {\tt scale} defaults to {\tt 1.0}.
+\item {\tt w} defaults to {\tt 400pt}.
+\item {\tt h} defaults to {\tt 600pt}.
+\end{itemize}
+The package creates then a destination box centered horizontally and vertically in the page and runs \verb|\includegraphics| with appropriate values set for the {\tt viewport} and {\tt crop} whenever it sees entries like
+\begin{verbatim}
+\scanpage[rot=-1,page=1,dx=20,dy=15]{scan-0} % page= only for pdf files
+%\index{}
+%\put(450,250){Is this assertion correct?}
+\endpicture\endgroup\newpage
+\end{verbatim}
+which it interprets as follows:
+\begin{itemize}
+\item
+if {\tt scan-0} is a blank string, a blank picture is produced, otherwise, if no corresponding graphic file can be found, {\tt graphicx} will stop with an error message;
+\item
+{\tt page=} will be understood only by {\tt.pdf} inclusions;
+\item
+{\tt rot} is an angle of rotation (degrees) in the mathematically positive sense (counter-clockwise) about the center. You may find it easier to enter {\tt tanrot=0.175}, the tangent of the rotation angle, as this is more easily estimated from the picture;
+{\tt page=1} selects the first page of the file {\tt scan-0.pdf}. This option may be omitted if the file contains only one page;
+\item {\tt dx} nudges the resulting picture to the right by {\tt 20bp}, and similarly for {\tt dy}. (Actually, {\tt dx} nudges the {\tt viewport} to the left by {\tt 20bp/scale}.) If no unit is provided, {\tt bp} is assumed;
+\item any material following the \verb|\scanpage| line and before \verb|\endpicture| can be used for index entries, table of contents entries, footnotes, additional graphic inclusions, annotations and the like. As the action is all taking place within a \LaTeX\ {\tt picture} environment with {\tt unitlength} set to {\tt1bp}, each visible item must be placed in an instruction of the form
+\begin{verbatim}
+\put(x,y){...}
+\end{verbatim}
+where {\tt x} and {\tt y} are purely numeric coordinates with implied unit {\tt 1bp}, which matches that required for dimensions in \verb|\includegraphics|.
+\end{itemize}
+
+The page it produces contains, in addition to the scan material and other embellishments, a superimposed grid with unit {\tt 1bp} and a black box marking the edge of outline of the destination box. After all adjustments are complete, the grid may be suppressed by adding the option {\tt nogrid} to the package option list.
+\subsection{Options to include the original page numbers}
+The \verb|\scanpage| macro also accepts three additional options that allow the page number from the original scanned document to be displayed.
+\begin{itemize}
+\item
+\verb|origpgnum=104| sets the current scanned page number to {\tt 104}, and specifies that this number should appear only when the {\tt grid} is in use---that is, except when the option {\tt nogrid} is in force. Unless modified by an option in a future page, the scanned page number will increment by one and display on all subsequent pages.
+\item \verb|origindest| specifies that the current scanned page number should be visible in the final document.
+\item \verb|origpgnumoff| prevents the scanned page number from appearing in either the final document or the grid, from this page forward.
+\item
+The format governing the display of the current scanned page number is set by the macro \verb|\origpgcmd|, whose default value is
+\begin{verbatim}
+\newcommand{\origpgcmd}{\put(400,-30){\texttt{Orig. page \# \the\origpgnum}}}
+\end{verbatim}
+which specifies that entries like
+\begin{verbatim}
+Orig. page # 104
+\end{verbatim}
+will appear with baseline {\tt 30bp} (about 3/8 in) below the target box and {\tt 400bp} ( about {\tt5.6in}) from its left edge. You may change this in your preamble, after loading {\tt scanpages}, with a similar line, like
+\begin{verbatim}
+\renewcommand{\origpgcmd}{...}
+\end{verbatim}
+
+
+\end{itemize}
+
+
+\subsection{Resetting the initial choices}
+The options you chose when loading the package may be changed in the middle of a document. Just insert
+\begin{verbatim}
+\initviewport{<scale>}{<llx>}{<lly>}{<w>}{<h>}
+\end{verbatim}
+to change your initial choice of options. E.g.,
+\begin{verbatim}
+\initviewport{.95}{3cm}{4cm}{8cm}{12cm}
+\end{verbatim}
+will in effect make {\tt scale=.95}, {\tt llx=3cm}, {\tt lly=4cm}, {\tt w=8cm} and {\tt h=12cm}.
+\section{Making a source entry for each page}
+Making more than a few entries by copy and paste, updating the indices, is quite boring, and I don't see how to manage this in \TeX, hence the need for the external scripts. The scripts operate on a file containing a small template that can generate what you need. I create a block of text like this:
+\begin{verbatim}
+%Repetitions=100
+%Variables={NNN,0:1+1,1:2+-2,2:[-200+300],3:1+1(3)}
+%%Begin page NNN0
+%\scanpage[rot=0,dx=NNN2,dy=0,page=NNN0]{pic}
+%%\index{}
+%\endpicture\endgroup\newpage
+\end{verbatim}
+The \verb|%Repetitions=|
+ line describes the maximum value of a counter starting at {\tt 1} that controls the iteration. The \verb|%Variables=|
+ line is less obvious.
+The fragment \verb|{NNN,0:1+1,1:2+-2,2:[-200+300],3:1+1(3)}| means that variables are named {\tt NNN0, NNN1, NNN2, NNN3}. Variable {\tt NNN0} is initially {\tt1}, increments by {\tt1} and so takes successive values {\tt 1,2,...,100}. Variable {\tt NNN1} is initially {\tt2} and increments by {\tt -2}, while variable {\tt NNN2} alternates between {\tt -200} for odd counter values and {\tt300} for even counter values. Variable {\tt NNN3} takes the same value as {\tt NNN0} but prints in a field of length {\tt 3}, padding as necessary on the left with {\tt0}'s so it substitutes successively {\tt 001,002,...,099,100}. (Note that commas, colons and plus signs are simply separators and have no arithmetic significance.) Running the script on this file will append 100 copies, the first two lines omitted, and with one \% stripped and variables replaced by their successive values. The first two resulting items appearing as
+\begin{verbatim}
+%Begin page 1
+\scanpage[rot=0,dx=-200,dy=0,page=1]{pic}
+%\index{}
+\endpicture\endgroup\newpage
+
+%Begin page 2
+\scanpage[rot=0,dx=300,dy=0,page=2]{pic}
+%\index{}
+\endpicture\endgroup\newpage
+\end{verbatim}
+ (The variable {\tt NNN1} was created with descriptor {\tt1:2+-2}, has initial value {\tt 2}, decreasing by {\tt 2} at each iteration, but was never used.)
+
+ Alternating variables can be useful with a scan taken from a two-sided document, where offsets may be quite different for odd and even pages. Note too that where variables that increment must be integer valued, alternating variables can be alphanumeric. For example, the descriptor {\tt2:[odd+even]} would work as expected.
+
+Two other special forms are available.
+\begin{itemize}
+\item
+Scanning software often places each scanned page in a separate file with names like {\tt scan-001.jpg}, {\tt scan-002.jpg}. In cover this case you need an integer variable padded to three places, which could be produced by the descriptor of the form {\tt 4:1+1(3)} and a pattern like:
+\begin{verbatim}
+%Repetitions=100
+%Variables={NNN,0:1+1,1:2+-2,2:[-200+300],4:1+1(3)}
+%%Begin page NNN0
+%\scanpage[rot=0,dx=NNN2,dy=0]{scan-NNN4}
+%%\index{}
+%\endpicture\endgroup\newpage
+\end{verbatim}
+\item If you are scanning two-sided material, you may end up with odd and even pages each saved in sequences of files like {\tt odd-0001.jpg}, {\tt odd-0002.jpg}, ... ,{\tt even-0001.jpg}, {\tt even-0002.jpg}, ... and in this case it is handy to use a descriptor that ``goes up by halves'' to give the sequence {\tt 0001, 0001, 0002, 0002,...}. The descriptor to use is like {\tt 3:2+1/2(4)}, which starts an internal counter at {\tt 2}, increments it by {\tt1} at each step, and prints half its value, truncated to an integer, and padded to length {\tt 4}. (If the {\tt(4)} had been omitted, there would have been no padding.) So the pattern to replicate would be like:
+\begin{verbatim}
+%Repetitions=100
+%Variables={NNN,0:1+1,1:[20+40],2:[odd+even],3:2+1/2(4)}
+%%Begin page NNN0
+%\scanpage[rot=0,dx=NNN1,dy=0]{NNN2-NNN3}
+%%\index{}
+%\endpicture\endgroup\newpage
+\end{verbatim}
+\end{itemize}
+\section{Whiting out scan artifacts}
+Use a white shape to overwrite scan artifacts. The package provides some macros to assist. Both are based on glyphs in a special font included as part of the {\tt scanpages} package, one a square shape and one a circular shape, each 500 units wide and tall, with zero depth and zero side-bearings. (A thousand units is equal to {\tt 1em}, so at with {\tt 10pt} typesetting, 500 units amounts to {\tt 5pt}.)
+\begin{verbatim}
+\whitesq(150,200){5} % width and height scaled by 5
+\whitesq(150,200){5}[2] % width scaled by 5, height by 2
+\end{verbatim}
+\begin{verbatim}
+\whitecirc(150,200){5} % width and height scaled by 5
+\whitecirc(150,200){5}[2] % width scaled by 5, height by 2
+\end{verbatim}
+the only difference being in the the shape of the of the region whited out. These macros make use of \verb|\scalebox| from the {\tt graphicx} package, and follow the same syntax for scale width and height.
+\section{Differences between the scripts}
+The AppleScript is meant to work within TeXShop after installation in the TeXShop Macros Menu---see instructions below. It works on the selected part of the file, and its output is placed in the same file, which can be part of a larger document. The \textsf{python} script is meant to run from the command line on a file containing just the pattern text, and produces output in the same file, which can then be copied than into your working {\tt.tex} document. Eg, if you copied the script into a directory on your {\tt PATH} and made it executable
+\begin{verbatim}
+replicate.py myfile.txt
+\end{verbatim}
+would read input from and write output to {\tt myfile.txt}. (The script has been tested with \textsf{python} {\tt2.7.4} under MacOS 10.9.2. It should work without modification under Linux but may require some minor changes in Windows using a \textsf{python} from {\tt activestate.com}.)
+The two scripts give the same output provided you use variable names that are identical in case to those the one in the \verb|%Variables=|
+line. (In the examples above, this was always {\tt NNN}.) The \textsf{python} script is case sensitive, but the AppleScript is not---it will act on any variant like {\tt nnn0} or {\tt NnN1} as well.
+\subsection{Installation in TeXShop's Macros Menu}
+Select \TeX Shop's Macros Menu and choose the top item---\textsf{Open Macro Editor ... }. Then, from the same menu, choose the second item---\textsf{Add macros from file ...}---and navigate to {\tt replicate.plist} in this distribution. When you choose that file, the AppleScript will be installed under the name \textsf{Replicate} in the Macros Menu.
+\section{Example}
+The last page of this document shows the result of using {\tt scanpage} with a blank filename, which does nothing but create a blank picture with a grid, then overwrite a part of the page with a portion of another. The illustration will not show the ({\tt nogrid}) final result.
+\begin{verbatim}
+\newpage
+\initviewport{1}{1in}{1in}{8cm}{12cm}
+\scanpage{}
+%viewport=xl yl xr yr
+\put(100,200){\includegraphics[viewport=165 530 300 700,clip]{pic1}}
+\endpicture\endgroup\newpage
+\end{verbatim}
+(A useful variant of this technique was suggested by my colleague Gill Williamson. Suppose your starting point is a hand-sketched graph or some other mathematical illustration. Scan the sketch and create a one-page document as described above on which you will make embellishments such as labels, then save this with no grid and import that document into your final larger document. This protects you from having to make many individual changes if you change the size of your picture so that the \verb|\put()| coordinates all have to be changed.)
+\newpage
+\initviewport{1}{1in}{1in}{8cm}{12cm}
+\scanpage{}
+%viewport=xl yl xr yr
+\put(100,200){\includegraphics[viewport=165 530 300 700,clip]{pic1}}
+\endpicture\endgroup\newpage
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/scanpages/map/scanpages.map b/macros/latex/contrib/scanpages/map/scanpages.map
new file mode 100644
index 0000000000..b5503df694
--- /dev/null
+++ b/macros/latex/contrib/scanpages/map/scanpages.map
@@ -0,0 +1 @@
+scanwipe scanwipe <scanwipe.pfb
diff --git a/macros/latex/contrib/scanpages/tex/scanpages.sty b/macros/latex/contrib/scanpages/tex/scanpages.sty
new file mode 100644
index 0000000000..56f2412230
--- /dev/null
+++ b/macros/latex/contrib/scanpages/tex/scanpages.sty
@@ -0,0 +1,177 @@
+\NeedsTeXFormat{LaTeX2e}
+
+% A package to help make a document based on scanned pages.
+%
+% Copyright (c) 2014--2016 by Michael Sharpe, msharpe at ucsd dot edu;
+% This is free software, subject to the LATEX Project Public License.
+
+\def\fileversion{1.05}
+\def\filedate{2016/10/09}
+\ProvidesPackage{scanpages}[\filedate\space v\fileversion]
+
+\message{`scanpages' v\fileversion, \filedate\space Macros to help create documents from scanned pages (msharpe)}
+%
+\RequirePackage{ifpdf}
+\RequirePackage{pgffor}
+\RequirePackage{xcolor}
+\RequirePackage{xkeyval}
+\RequirePackage{fp-basic}
+\RequirePackage{graphicx}
+\RequirePackage{etoolbox}
+%\RequirePackage{trace}
+\ifpdf\else
+ \@latex@error{Must be processed with pdf[la]tex!}\@eha
+\fi
+\newif\ifscanp@nogrid
+\define@boolkey{scanp}{nogrid}[true]{%
+\csname scanp@nogrid#1\endcsname}
+\def\scanp@origscale{1.0}
+\def\scanp@srcscale{1.0}
+\def\scanp@invscale{1.0}
+\define@key{scanp}{scale}[1.0]{\def\scanp@srcscale{#1}}
+\def\scanp@llx{1in}
+\def\scanp@lly{1in}
+\def\scanp@srcw{400\p@}
+\def\scanp@srch{600\p@}
+\define@key{scanp}{llx}[0]{\def\scanp@llx{#1}}%
+\define@key{scanp}{lly}[0]{\def\scanp@lly{#1}}%
+\define@key{scanp}{w}[0]{\def\scanp@srcw{#1}}%
+\define@key{scanp}{h}[0]{\def\scanp@srch{#1}}%
+\DeclareOption*{%
+ \begingroup
+ \edef\x{\endgroup
+ \noexpand\setkeys{scanp}{\CurrentOption}}%
+ \x}
+\ProcessOptions*
+\def\bp@ratio{.99264} % factor to multiply num of pt to get num of bp
+
+%new
+\newcommand{\origpgcmd}{\put(400,-30){p.\ $\the\origpgnum$ in orig.}}
+\newcount\origpgnum %page in original
+\newif\ifscanp@origindest
+\newif\ifscanp@origingrid
+\newif\ifscanp@change
+% end new
+\newcount\scanp@pgcnt
+\setlength\unitlength{1bp}
+\long\def\putn(#1,#2)#3{%
+ \@killglue%
+ \dimen0\@picht\advance\dimen0 -#2\unitlength%
+ \raise\dimen0\hb@xt@\z@{\kern#1\unitlength #3\hss}
+ \ignorespaces}
+\def\unitlength@off{\let\@unitlength\ignorespaces\ignorespaces}
+\def\scanp@setlength#1#2{% if #2 has no dimension, append dimension
+ \let\@unitlength\unitlength
+ \afterassignment\unitlength@off
+ #1 #2\@unitlength%
+}
+\def\scanp@addtolength#1#2{% if #2 has no dimension, append dimension
+ \let\@unitlength\unitlength
+ \afterassignment\unitlength@off
+ \advance#1 #2\@unitlength%
+}
+\newdimen\scanp@dwdim\newdimen\scanp@dhdim % dest width and height
+\newdimen\scanp@swdim\newdimen\scanp@shdim % src width and height
+\newdimen\scanp@dwdimbp\newdimen\scanp@dhdimbp % dest width and height in bp
+\newdimen\scanp@xindent\newdimen\scanp@yindent
+\newdimen\scanp@xl\newdimen\scanp@yl\newdimen\scanp@xr\newdimen\scanp@yr
+\newdimen\scanp@xlbp\newdimen\scanp@ylbp\newdimen\scanp@xrbp\newdimen\scanp@yrbp\newdimen\@dima
+%
+\def\initviewport#1#2#3#4#5{% srcscale,llx,lly,srcw,srch
+\scanp@pgcnt=\z@
+\edef\scanp@srcscale{#1}
+\FPdiv{\scanp@invscale}{1.0}{\scanp@srcscale}
+\edef\scanp@llx{#2}
+\edef\scanp@lly{#3}
+\edef\scanp@srcw{#4}
+\edef\scanp@srch{#5}
+\scanp@setlength{\scanp@swdim}{\scanp@srcw}
+\scanp@setlength{\scanp@shdim}{\scanp@srch}
+\scanp@dwdim=\scanp@srcscale\scanp@swdim
+\scanp@dhdim=\scanp@srcscale\scanp@shdim
+\scanp@dwdimbp=\bp@ratio\scanp@dwdim
+\scanp@dhdimbp=\bp@ratio\scanp@dhdim
+\scanp@setlength{\scanp@xl}{\scanp@llx}
+\scanp@setlength{\scanp@yl}{\scanp@lly}
+\scanp@xr=\scanp@xl \advance\scanp@xr\scanp@swdim
+\scanp@yr=\scanp@yl \advance\scanp@yr\scanp@shdim
+\scanp@xindent=\textwidth \scanp@yindent=\textheight
+\advance\scanp@xindent -\scanp@dwdim\advance\scanp@yindent -\scanp@dhdim
+\scanp@xindent=0.5\scanp@xindent\scanp@yindent=0.5\scanp@yindent
+\advance\scanp@yindent -14\p@
+}
+\initviewport{\scanp@srcscale}{\scanp@llx}{\scanp@lly}{\scanp@srcw}{\scanp@srch}
+%
+\def\whitesq(#1)#2{%
+\@ifnextchar[{\whitesq@(#1){#2}}{\whitesq@(#1){#2}[#2]}}
+\long\def\whitesq@(#1)#2[#3]{\put(#1){\scalebox{#2}[#3]{\color{white}{\usefont{U}{scanwipe}{m}{n}\char"00}}}}
+\def\whitecirc(#1)#2{%
+\@ifnextchar[{\whitecirc@(#1){#2}}{\whitecirc@(#1){#2}[#2]}}
+\long\def\whitecirc@(#1)#2[#3]{\put(#1){\scalebox{#2}[#3]{\color{white}{\usefont{U}{scanwipe}{m}{n}\char"01}}}}
+%
+%\newdimen\scanp@whw\newdimen\scanp@whh %width, height of whiteout
+%\def\whiteout(#1)#2#3{\scanp@setlength{\scanp@whw}{#2}%
+%\scanp@setlength{\scanp@whh}{#3}%
+%\put(#1){\color{white}\fcolorbox{white}{white}{\vrule width \the\scanp@whw height \the\scanp@whh}}}
+
+\define@key{scanpi}{origpgnum}{\global\origpgnum=#1 \global\scanp@origingridtrue}
+\define@boolkey{scanpi}{origindest}[true]{\csname scanp@change#1\endcsname}
+\define@boolkey{scanpi}{origpgnumoff}[true]{\global\scanp@origindestfalse\global\scanp@origingridfalse}
+\define@key{scanpi}{dx}{\def\scanp@dx{#1}}
+\define@key{scanpi}{dy}{\def\scanp@dy{#1}}
+\define@key{scanpi}{page}{\def\scanp@page{#1}}
+\define@key{scanpi}{rot}{\def\scanp@rot{#1}}
+\define@key{scanpi}{tanrot}{\def\scanp@skew{#1}}
+\newdimen\scanp@dxdim\newdimen\scanp@dydim
+%
+\def\scanpage{\@ifnextchar[\scanpage@i{\scanpage@i[]}}
+\def\scanpage@i[#1]#2{\advance\scanp@pgcnt\@ne\begingroup\setkeys{scanpi}{#1}%
+\ifscanp@change\global\scanp@origindesttrue %
+ \global\scanp@origingridfalse %
+ \global\scanp@changefalse \fi%
+\edef\scanp@head{\noexpand\vspace*{\scanp@yindent}\noexpand\noindent\noexpand\hspace*{\scanp@xindent}\noexpand\picture(\strip@pt\scanp@dwdimbp,\strip@pt\scanp@dhdimbp)}
+%\edef\@x{\strip@pt\scanp@dwdimbp}\edef\@y{\strip@pt\scanp@dhdimbp}
+%\vspace*{\the\scanp@yindent}\noindent\hspace*{\scanp@xindent}\picture(\@x,\@y)
+\ifdefvoid{\scanp@dx}{}{\scanp@setlength\scanp@dxdim{-\scanp@dx}\scanp@dxdim=\scanp@invscale\scanp@dxdim\advance\scanp@xl \scanp@dxdim \advance\scanp@xr \scanp@dxdim}
+\ifdefvoid{\scanp@dy}{}{\scanp@setlength\scanp@dydim{-\scanp@dy}\scanp@dydim=\scanp@invscale\scanp@dydim\advance\scanp@yl \scanp@dydim \advance\scanp@yr \scanp@dydim}
+\scanp@xlbp=\bp@ratio\scanp@xl
+\scanp@xrbp=\bp@ratio\scanp@xr
+\scanp@ylbp=\bp@ratio\scanp@yl
+\scanp@yrbp=\bp@ratio\scanp@yr
+%\ifblank{#2}{\global\scanp@blanktrue}{}
+\edef\scanp@cmd{viewport=\strip@pt\scanp@xlbp\space\strip@pt\scanp@ylbp\space\strip@pt\scanp@xrbp\space\strip@pt\scanp@yrbp, clip]{#2}}
+\ifdefvoid{\scanp@rot}{%
+\ifdefvoid{\scanp@skew}{}{%
+\@dima=\scanp@skew\p@\@dima=57.14\@dima\edef\scanp@cmd{angle=\strip@pt\@dima,origin=c,\scanp@cmd}}}{\edef\scanp@cmd{angle=\scanp@rot,origin=c,\scanp@cmd}}%
+\if\scanp@srcscale\scanp@origscale\else\edef\scanp@cmd{scale=\scanp@srcscale,\scanp@cmd}\fi
+\ifdefvoid{\scanp@page}{}{\edef\scanp@cmd{page=\scanp@page,\scanp@cmd}}
+\edef\scanp@cmd{\noexpand\scanp@head\noexpand\put(0,0){\noexpand\includegraphics[\scanp@cmd}}
+\ifblank{#2}{\scanp@head}{\scanp@cmd} % \begingroup, start \picture, \put pdf at (0,0)
+\ifscanp@origindest\origpgcmd\fi
+\thegrid{\strip@pt\scanp@dwdimbp}{\strip@pt\scanp@dhdimbp}%
+\global\advance\origpgnum\@ne}
+
+\ifscanp@nogrid\def\thegrid#1#2{}\else%
+\long\def\thegrid#1#2{\edef\scanp@gcmd{\noexpand\put(0,0){\noexpand\line(1,0){#1}}
+\noexpand\put(0,0){\noexpand\line(0,1){#2}}
+\noexpand\put(#1,0){\noexpand\line(0,1){#2}}
+\noexpand\put(0,#2){\noexpand\line(1,0){#1}}}
+\foreach\x in{-400,-390,...,800}{%
+ \put(-400,\x){\color{red!20}\line(1,0){1000}}%
+ }
+\foreach\x in {-300,-290,...,550}{%
+ \put(\x,-500){\color{red!20}\line(0,1){1500}}%
+}
+\foreach\x in {-400,-350,...,800}{%
+ \put(-400,\x){\color{red!50}\line(1,0){1000}}%
+ \put(-20,\x){\x}
+ }
+\foreach\x in {-300,-250,...,550}{%
+ \put(\x,-500){\color{red!50}\line(0,1){1500}}%
+ \put(\x,-15){\x}}
+\put(0,-30){\color{blue}Page \the\scanp@pgcnt}%
+\scanp@gcmd%
+\ifscanp@origingrid\origpgcmd\fi}
+\fi % end \ifscanp@nogrid
+
+\endinput \ No newline at end of file
diff --git a/macros/latex/contrib/scanpages/tex/uscanwipe.fd b/macros/latex/contrib/scanpages/tex/uscanwipe.fd
new file mode 100644
index 0000000000..2318f466d7
--- /dev/null
+++ b/macros/latex/contrib/scanpages/tex/uscanwipe.fd
@@ -0,0 +1,6 @@
+\ProvidesFile{uscanwipe.fd}
+ [ scanwipe (Unknown encoding)]
+\DeclareFontFamily{U}{scanwipe}{}
+\DeclareFontShape{U}{scanwipe}{m}{n}{
+<-> scanwipe.tfm}{}
+\endinput
diff --git a/macros/latex/contrib/scanpages/tfm/scanwipe.tfm b/macros/latex/contrib/scanpages/tfm/scanwipe.tfm
new file mode 100644
index 0000000000..eb591c0f2f
--- /dev/null
+++ b/macros/latex/contrib/scanpages/tfm/scanwipe.tfm
Binary files differ
diff --git a/macros/latex/contrib/scanpages/type1/scanwipe.pfb b/macros/latex/contrib/scanpages/type1/scanwipe.pfb
new file mode 100644
index 0000000000..adec8f8a6a
--- /dev/null
+++ b/macros/latex/contrib/scanpages/type1/scanwipe.pfb
Binary files differ