summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2014-01-07 23:07:05 +0000
committerKarl Berry <karl@freefriends.org>2014-01-07 23:07:05 +0000
commit57d395428d45725bb0bae19829460622dbbb124f (patch)
tree9d944e5b0c4f73b721323ab19758a7b83a0bf4c6
parentea751c100642b9b81c97ad32b1b492c917d5a93c (diff)
scanpages (7jan14)
git-svn-id: svn://tug.org/texlive/trunk@32600 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/scanpages/README21
-rw-r--r--Master/texmf-dist/doc/latex/scanpages/replicate.plist190
-rwxr-xr-xMaster/texmf-dist/doc/latex/scanpages/replicate.py113
-rw-r--r--Master/texmf-dist/doc/latex/scanpages/scanpages-doc.pdfbin0 -> 50282 bytes
-rw-r--r--Master/texmf-dist/doc/latex/scanpages/scanpages-doc.tex145
-rw-r--r--Master/texmf-dist/tex/latex/scanpages/scanpages.sty143
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check3
-rw-r--r--Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/scanpages.tlpsrc0
9 files changed, 615 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/scanpages/README b/Master/texmf-dist/doc/latex/scanpages/README
new file mode 100644
index 00000000000..646d9946451
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/scanpages/README
@@ -0,0 +1,21 @@
+LaTeX package scanpages
+#======================
+# Copyright 2014 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.
+
+Version: 1.0
+
+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/Master/texmf-dist/doc/latex/scanpages/replicate.plist b/Master/texmf-dist/doc/latex/scanpages/replicate.plist
new file mode 100644
index 00000000000..e4a09ea1772
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/scanpages/replicate.plist
@@ -0,0 +1,190 @@
+<?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, 20140106
+--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
+
+set TSLibAlias to alias ((path to home folder as string) &amp; "Library:TeXShop:Scripts:TSLib.scpt")
+set TSLib to (load script TSLibAlias)
+set lf to (ASCII character 10)
+tell application "TeXShop" to set s to content of selection of document 1
+set AppleScript's text item delimiters to {""}
+
+set oldtid to AppleScript's text item delimiters
+set AppleScript's text item delimiters to "%Repetitions="
+set tmp to (text items of s)
+set AppleScript's 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 AppleScript's text item delimiters to {lf}
+set ss to (item 2 of tmp)
+set tmp2 to (text items of ss)
+set AppleScript's text item delimiters to oldtid
+set numrep to (item 1 of tmp2) as integer
+--next get variable names
+set AppleScript's text item delimiters to {"%Variables="}
+set tmp to (text items of s)
+set AppleScript's 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 AppleScript's text item delimiters to {lf}
+set tmp2 to (text items of ss)
+--display dialog "tmp2=" &amp; (tmp2 as text)
+set AppleScript's text item delimiters to oldtid
+set vbllst to (item 1 of tmp2) --like {nnn,0:1+1,1:3+-2}
+--tell TSLib to set trimitems to {" ", tab, "{", "}"}
+tell TSLib to set vbllst2 to trim(vbllst)
+set vbllst3 to (text 2 thru -2 of vbllst2)
+set AppleScript's 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 AppleScript's 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 AppleScript's 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 AppleScript's text item delimiters to oldtid
+--set v to (vlst as text)
+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 AppleScript's text item delimiters to {lf}
+set tmp to (text items of s)
+set AppleScript's text item delimiters to oldtid
+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 AppleScript's text item delimiters to {lf}
+set body to (tmp2 as text)
+set AppleScript's text item delimiters to oldtid
+--Start new method
+set repl to {s}
+set newbody to body
+repeat with p from 1 to numrep
+ --copy tmp to newtmp
+ 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 AppleScript's 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
+</string>
+ <key>name</key>
+ <string>Replicate</string>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/Master/texmf-dist/doc/latex/scanpages/replicate.py b/Master/texmf-dist/doc/latex/scanpages/replicate.py
new file mode 100755
index 00000000000..99f0395da35
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/scanpages/replicate.py
@@ -0,0 +1,113 @@
+#!/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:
+ s=f.read()
+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')
+
diff --git a/Master/texmf-dist/doc/latex/scanpages/scanpages-doc.pdf b/Master/texmf-dist/doc/latex/scanpages/scanpages-doc.pdf
new file mode 100644
index 00000000000..99e46610243
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/scanpages/scanpages-doc.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/scanpages/scanpages-doc.tex b/Master/texmf-dist/doc/latex/scanpages/scanpages-doc.tex
new file mode 100644
index 00000000000..1438d9527bc
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/scanpages/scanpages-doc.tex
@@ -0,0 +1,145 @@
+\documentclass[11pt]{article}
+\usepackage[margin=1in]{geometry}
+\usepackage[parfill]{parskip}% Begin paragraphs with an empty line rather than an indent
+\usepackage{graphicx}
+\usepackage{amssymb}% do not use with mtpro2 except lite version
+%SetFonts
+% libertine+newtxmath
+\usepackage[lining]{libertine}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+\usepackage[scaled=.85]{beramono}
+\usepackage{amsmath,amsthm}
+\usepackage[libertine,bigdelims]{newtxmath}
+\useosf
+\usepackage[supstfm=libertinesups,%
+ supscaled=1.2,%
+ raised=-.13em]{superiors}
+%SetFonts
+\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}. 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 so each page will potentially 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 governed by 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 four critical dimensions are:
+\begin{itemize}
+\item
+The $x$ and $y$ coordinates {\tt llx, lly} of the lower left corner of the image region relative to the lower left corner of the 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 whenever it sees entries like
+\begin{verbatim}
+\scanpage[rot=-1,page=1,dx=20,dy=15]{scan-0}
+%\index{}
+%\rput(450,250){Is this assertion correct?}
+\endpicture
+\newpage
+\end{verbatim}
+which it interprets as follows:
+\begin{itemize}
+\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, 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 is 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 and the like. As the action is all taking place within a \LaTeX\ {\tt picture} environment, each visible item must be placed in an instruction of the form
+\begin{verbatim}
+\rput(x,y){...}
+\end{verbatim}
+where {\tt x} and {\tt y} are the 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{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. Eg,
+\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
+%\newpage
+\end{verbatim}
+The \verb|%Repetitions=|
+ line describes the maximum value of a counter starting at {\tt 1} that controls the iteration. The line \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
+\newpage
+
+%Begin page 2
+\scanpage[rot=0,dx=300,dy=0,page=2]{pic}
+%\index{}
+\endpicture
+\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
+%\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
+%\newpage
+\end{verbatim}
+\end{itemize}
+\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.1. 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.
+\end{document} \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/scanpages/scanpages.sty b/Master/texmf-dist/tex/latex/scanpages/scanpages.sty
new file mode 100644
index 00000000000..2e4dd3833f2
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/scanpages/scanpages.sty
@@ -0,0 +1,143 @@
+\NeedsTeXFormat{LaTeX2e}
+
+% A package to help make a document based on scanned pages.
+%
+% Copyright (c) 2014 by Michael Sharpe, msharpe at ucsd dot edu;
+% This is free software, subject to the LATEX Project Public License.
+
+\def\fileversion{1.00}
+\def\filedate{2014/01/06}
+\ProvidesPackage{scanpages.sty}[\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{keyval}
+\RequirePackage{fp-basic}
+\RequirePackage{graphicx}
+\RequirePackage{etoolbox}
+\ifpdf\else
+ \@latex@error{Must be processed in 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*
+
+\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\bp@ratio{.99264} % factor to multiply num of pt to get num of bp
+\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
+\FPdiv\scanp@invscale{1.0}{\scanp@srcscale}
+\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}{#2}
+\scanp@setlength{\scanp@yl}{#3}
+\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@srcw}
+%
+\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{{\setkeys{scanpi}{#1}%
+\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
+\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}}
+%\show\scanp@cmd%
+\scanp@cmd
+\thegrid{\strip@pt\scanp@dwdimbp}{\strip@pt\scanp@dwdimbp}
+\endpicture
+\newpage}}
+
+\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}%
+\scanp@gcmd%
+}}
+\fi % end \ifscanp@nogrid
+
+\endinput \ No newline at end of file
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index d88d22c1aa1..238b38252d6 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -410,7 +410,8 @@ my @TLP_working = qw(
sa-tikz sageep sansmath sansmathaccent sansmathfonts
sapthesis sasnrdisplay sauerj
sauterfonts savefnmark savesym savetrees
- scale scalebar scalerel schemabloc schemata schulschriften schwalbe-chess
+ scale scalebar scalerel scanpages
+ schemabloc schemata schulschriften schwalbe-chess
sciposter screenplay scrjrnl
sdrt
secdot section sectionbox sectsty selectp selnolig semantic semaphor
diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
index 07d533e0d61..9d8e1f44ea4 100644
--- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
@@ -707,6 +707,7 @@ depend savetrees
depend scale
depend scalebar
depend scalerel
+depend scanpages
depend sdrt
depend secdot
depend sectionbox
diff --git a/Master/tlpkg/tlpsrc/scanpages.tlpsrc b/Master/tlpkg/tlpsrc/scanpages.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/scanpages.tlpsrc