Discussion:
add serial numbers to multiple copies of a file?
(too old to reply)
wes
2011-05-15 21:08:05 UTC
Permalink
I am going to print out many copies of an exam.

Ideally, I would like to add a "serial number" to each exam, to
indicate it's position in the sequence. (If there is later evidence
that there may have been copying between two exams, the serial number
can indicate that they were actually unlikely to be close to each
other.)

Does anyone know how to do this in a simple, automated way through
latex?

Thanks for any help,
Wes
Peter Flynn
2011-05-15 22:51:57 UTC
Permalink
Post by wes
I am going to print out many copies of an exam.
Ideally, I would like to add a "serial number" to each exam, to
indicate it's position in the sequence. (If there is later evidence
that there may have been copying between two exams, the serial number
can indicate that they were actually unlikely to be close to each
other.)
Does anyone know how to do this in a simple, automated way through
latex?
To do it through LaTeX you would need to re-run LaTeX each time,
generating a new PDF (or DVI) file with the required number, printing
it, and then doing the next one.

If the number of copies needed is small, this is the best way, but
tedious unless you write a script.

Or I guess you could get LaTeX itself to keep re-outputting the same
page[s] again and again, with a different number each time. Maybe
someone has written a package to do this.

If the number of copies is very large, I'd write a small control script
that would create a .ps file from DVI, run sed over the .ps file to
increment the counter, and then print and do the next one.

///Peter
Bruno Le Floch
2011-05-16 03:20:42 UTC
Permalink
Post by Peter Flynn
Post by wes
I am going to print out many copies of an exam.
Ideally, I would like to add a "serial number" to each exam, to
indicate it's position in the sequence.  (If there is later evidence
that there may have been copying between two exams, the serial number
can indicate that they were actually unlikely to be close to each
other.)
Does anyone know how to do this in a simple, automated way through
latex?
To do it through LaTeX you would need to re-run LaTeX each time,
generating a new PDF (or DVI) file with the required number, printing
it, and then doing the next one.
If the number of copies needed is small, this is the best way, but
tedious unless you write a script.
Or I guess you could get LaTeX itself to keep re-outputting the same
page[s] again and again, with a different number each time. Maybe
someone has written a package to do this.
If the number of copies is very large, I'd write a small control script
that would create a .ps file from DVI, run sed over the .ps file to
increment the counter, and then print and do the next one.
///Peter
Would it be possible to insert some ps code to get the printer to do
it?
I.e. each time you print, increment a counter somewhere by 1, and use
it in the file.

I don't know ps, though...
Bruno
GL
2011-05-16 08:54:44 UTC
Permalink
Post by Bruno Le Floch
Post by Peter Flynn
Post by wes
I am going to print out many copies of an exam.
Ideally, I would like to add a "serial number" to each exam, to
indicate it's position in the sequence. (If there is later evidence
that there may have been copying between two exams, the serial number
can indicate that they were actually unlikely to be close to each
other.)
Does anyone know how to do this in a simple, automated way through
latex?
To do it through LaTeX you would need to re-run LaTeX each time,
generating a new PDF (or DVI) file with the required number, printing
it, and then doing the next one.
If the number of copies needed is small, this is the best way, but
tedious unless you write a script.
Or I guess you could get LaTeX itself to keep re-outputting the same
page[s] again and again, with a different number each time. Maybe
someone has written a package to do this.
If the number of copies is very large, I'd write a small control script
that would create a .ps file from DVI, run sed over the .ps file to
increment the counter, and then print and do the next one.
///Peter
Would it be possible to insert some ps code to get the printer to do
it?
I.e. each time you print, increment a counter somewhere by 1, and use
it in the file.
I don't know ps, though...
Bruno
Instead of writting a script to do the job, let's say TeX knows how to
typeset a number (in any font, possibly inside a box or a circle etc.)

Then at each compilation:
\newcount \examcountersequence

At begin document (after .aux has been read):
\global\advance\examcountersequence by 1

For the next compilation :
\immediate\write\@auxout
{\examcountersequence = \the\examcountersequence }

The counter is here.

Now you can write a script that runs LaTeX 267 times because there
are 267 candidates. And you get 267 .pdf files !


Well: Let's say the content of the exam in inside "exam.tex"
Then the main LaTeX file contains:

\begin{document}

\clearpage
\input exam.tex % 267 times

% This is :
\loop \input exam.tex \ifnum \examcountersequence <267
\global\advance\examcountersequence by 1
\repeat

\end{document}

And you get 1 .pdf files with 267 copies of the exams.
exam.tex uses \examcountersequence to typeset the number (possibly
as a watermark ;-) )

Regards.
Ulrich D i e z
2011-05-16 14:36:53 UTC
Permalink
Post by GL
Instead of writting a script to do the job, let's say TeX knows how to
typeset a number (in any font, possibly inside a box or a circle etc.)
\newcount \examcountersequence
\global\advance\examcountersequence by 1
{\examcountersequence = \the\examcountersequence }
The counter is here.
Now you can write a script that runs LaTeX 267 times because there
are 267 candidates. And you get 267 .pdf files !
In case \write18 is enabled and the \jobname-option is
available, you could as well make (La)TeX
- increment a numerical value in a count-register or (via \numexpr)
in a macro and
- via \write18 call (pdf)LaTeX on the actual exam-file while within
that \write18-call having defined a
macro from the incremented value.
That macro will be used within the exam-file and the \jobname-option
can be used together with that incremented value for creating
another output-file name for each pdf-file.

(You could as well use this technique for automatically
creating sets of exercises and solution-sheets of exactly
the same pattern and with the same text and enumeration
but with slightly different coefficients. This way you could
probably deal the "copying-issue" in a very interesting way...)
Post by GL
Well: Let's say the content of the exam in inside "exam.tex"
\begin{document}
\clearpage
\input exam.tex % 267 times
\loop \input exam.tex \ifnum \examcountersequence <267
\global\advance\examcountersequence by 1
\repeat
\end{document}
And you get 1 .pdf files with 267 copies of the exams.
exam.tex uses \examcountersequence to typeset the number (possibly
as a watermark ;-) )
If in this case \label and \ref are used, make sure to include the
value of the counter \examcountersequence into the name of
each label in order to avoid duplicate-reference-errors.

E. g.:
[...]
\Exercise \label{\number\the\examcountersequence some exercise}

This is the text of .some exerxise
[...]
\Exercise \label{\number\the\examcountersequence this exercise}

This is the text of this exerxise:
Use the result of exercise \ref{\number\the\examcountersequence some exercise}
for accomplishing this exercise.
[...]


Ulrich
GL
2011-05-16 17:33:22 UTC
Permalink
Post by Ulrich D i e z
Post by GL
Instead of writting a script to do the job, let's say TeX knows how to
typeset a number (in any font, possibly inside a box or a circle etc.)
\newcount \examcountersequence
\global\advance\examcountersequence by 1
{\examcountersequence = \the\examcountersequence }
The counter is here.
Now you can write a script that runs LaTeX 267 times because there
are 267 candidates. And you get 267 .pdf files !
In case \write18 is enabled and the \jobname-option is
available, you could as well make (La)TeX
- increment a numerical value in a count-register or (via \numexpr)
in a macro and
- via \write18 call (pdf)LaTeX on the actual exam-file while within
that \write18-call having defined a
macro from the incremented value.
That macro will be used within the exam-file and the \jobname-option
can be used together with that incremented value for creating
another output-file name for each pdf-file.
(You could as well use this technique for automatically
creating sets of exercises and solution-sheets of exactly
the same pattern and with the same text and enumeration
but with slightly different coefficients. This way you could
probably deal the "copying-issue" in a very interesting way...)
Post by GL
Well: Let's say the content of the exam in inside "exam.tex"
\begin{document}
\clearpage
\input exam.tex % 267 times
\loop \input exam.tex \ifnum \examcountersequence<267
\global\advance\examcountersequence by 1
\repeat
\end{document}
And you get 1 .pdf files with 267 copies of the exams.
exam.tex uses \examcountersequence to typeset the number (possibly
as a watermark ;-) )
If in this case \label and \ref are used, make sure to include the
value of the counter \examcountersequence into the name of
each label in order to avoid duplicate-reference-errors.
Yes of course. Global counters (for Problems or Exercices for example)
should be cleaned as well etc. if there is any...

The fact is that it's obviously more satisfying to finally get one
single pdf file to print out, than 267 files...
Post by Ulrich D i e z
[...]
\Exercise \label{\number\the\examcountersequence some exercise}
This is the text of .some exerxise
[...]
\Exercise \label{\number\the\examcountersequence this exercise}
Use the result of exercise \ref{\number\the\examcountersequence some exercise}
for accomplishing this exercise.
[...]
Ulrich
Ulrich D i e z
2011-05-17 01:04:36 UTC
Permalink
Post by GL
Post by Ulrich D i e z
If in this case \label and \ref are used, make sure to include the
value of the counter \examcountersequence into the name of
each label in order to avoid duplicate-reference-errors.
Yes of course. Global counters (for Problems or Exercices for example)
should be cleaned as well etc. if there is any...
According to the LaTeX2e-sources, file m:ltcounts.dtx, there is
the macro \cl@@ckpt which holds an \@elt-list for all counters
defined via \newcounter.

It is used for taking checkpoints for the \include-system.
You can (ab)use it for getting a checkpoint into a macro
for later resetting counters.

Heiko Oberdiek provided \HyperDestNameFilter for the hyperref-
package which can be used for providing a unique prefix to
each anchor-name, ensuring no duplicate anchors will be created.

Getting bookmarks right is a bit of fun as \HyperDestNameFilter
by default is not applied when writing bookmarks to the .out-file
but is applied internally by the \BOOKMARK-command when
reading the .out-file which makes maintaining bookmarks
with different anchor-name-prefixes impossible. But this can
be changed easily.

Putting the pieces together, I can propose the following template:


\documentclass{article}
\usepackage{hyperref}

\makeatletter

%% put \include-checkpoints into macros:
\newcommand*\UDptelt[1]{%
\noexpand\setcounter{#1}{\the\@nameuse{c@#1}}%
}%
\newcommand\UDckpttomacroglobal[1]{%
\begingroup
\let\@elt\UDptelt
\xdef#1{\cl@@ckpt}%
\endgroup
}%

%% patch bookmarking:
\def\@@BOOKMARK[#1][#2]#3#4#5{%
\expandafter\edef\csname @count@#3\endcsname{%
\the\@***@counter
}%
\edef\@mycount{\the\@***@counter}%
\***@StepCount\@***@counter
\edef\@parcount{%
\expandafter\ifx\csname @count@#5\endcsname\relax
0%
\else
\csname @count@#5\endcsname
\fi
}%
\immediate\special{%
%%% !!! next line changed:
!outline #3;p=\@parcount,i=\@mycount,%
s=\ifx#2-c\else o\fi,t=#4%
}%
}%

\def\***@writebookmark#1#2#3#4#5{%
% section number, text, label, level, file
\ifx\WriteBookmarks\relax%
\else
\ifnum#4>\***@bookmarksdepth\relax
\else
%%% !!! next line changed:
\@@writetorep{#1}{#2}{\HyperDestNameFilter{#3}}{#4}{#5}%
\fi
\fi
}

\let\***@write=\***@write

\def\@@writetorep#1#2#3#4#5{%
\begingroup
\edef\***@tempa{#5}%
\ifx\***@tempa\***@bookmarkstype
\edef\***@level{#4}%
\ifx\***@levelcheck Y%
\@tempcnta\***@level\relax
\advance\@tempcnta by -1 %
\ifnum\***@currentbookmarklevel<\@tempcnta
\advance\@tempcnta by -\***@currentbookmarklevel\relax
\advance\@tempcnta by 1 %
\***@Warning{%
Difference (\the\@tempcnta) between bookmark levels is %
greater \MessageBreak than one, level fixed%
}%
\@tempcnta\***@currentbookmarklevel
\advance\@tempcnta by 1 %
\edef\***@level{\the\@tempcnta}%
\fi
\else
\global\let\***@levelcheck Y%
\fi
\global\let\***@currentbookmarklevel\***@level
\@tempcnta\***@level\relax
\expandafter\xdef\csname Parent\***@level\endcsname{#3}%
\advance\@tempcnta by -1 %
\edef\***@tempa{#3}%
\edef\***@tempb{\csname Parent\the\@tempcnta\endcsname}%
\ifx\***@tempa\***@tempb
\***@Warning{%
The anchor of a bookmark and its parent's must not%
\MessageBreak be the same. Added a new anchor%
}%
\phantomsection
\fi
\***@bookmarksnumbered
\let\numberline\***@numberline
\let\booknumberline\***@numberline
\let\partnumberline\***@numberline
\let\chapternumberline\***@numberline
\else
\let\numberline\@gobble
\let\booknumberline\@gobble
\let\partnumberline\@gobble
\let\chapternumberline\@gobble
\fi
%%% !!! next 2 lines changed:
\@ifundefined{***@XeTeXBigCharstrue}%
{}{\***@XeTeXBigCharstrue}%
\pdfstringdef\***@tempa{#2}%
%%% !!! next 2 lines changed:
\@ifundefined{***@SanitizeForOutFile}%
{}{\***@SanitizeForOutFile\***@tempa}%
%%% !!! next line changed:
% \***@filesw
\stepcounter{***@seq@number}%
\@ifundefined{@outlinefile}{%
}{%
%%% !!! next line changed:
\***@write\@outlinefile{}{%
\protect\BOOKMARK
[\***@level][\@bookmarkopenstatus{\***@level}]{#3}%
{\***@tempa}{\***@tempb}%
\@percentchar\space\***@seq@number
}%
}%
%%% !!! next line changed:
% \fi
\fi
\endgroup
}
%% Bookmarking-patching done.
\makeatother


\begin{filecontents*}{UDtest}
\section{\texorpdfstring{Exam}{Exam (sheet \examcountersequence)}}
That's the test/exam.
The value of \texttt{\string\examcountersequence} is \examcountersequence.
\subsection{some exercise}\label{\HyperDestNameFilter{some exercise}}%
This is an exercise.
\subsection{other exercise}
This is another exercise. Please use the result of exercise
\ref{\HyperDestNameFilter{some exercise}}.
\end{filecontents*}

\begin{document}

\begingroup
\UDckpttomacroglobal{\UDResetCounters}%

\newcommand\examcountersequence{0}
\loop
\edef\examcountersequence{\number\numexpr\examcountersequence+1\relax}%
\edef\HyperDestNameFilter##1{Sheet_\examcountersequence_##1}%
\UDResetCounters
\input{UDtest}%
\cleardoublepage
\ifnum \examcountersequence<10 \repeat
\endgroup

\end{document}





Ulrich
Ulrich D i e z
2011-05-17 10:46:52 UTC
Permalink
[...]

Meanwhile I think patching bookmarking can be done more
easily by concentrating on \***@writebookmark.

Ulrich


\documentclass{article}
\usepackage{hyperref}
\usepackage{bookmark}

\makeatletter

%% put \include-checkpoints into macros:
\newcommand*\UDptelt[1]{%
\expandafter\ifx\csname c@#1\endcsname\***@bookmark@***@number
\else
\noexpand\setcounter{#1}{\the\@nameuse{c@#1}}%
\fi
}%
\newcommand\UDckpttomacroglobal[1]{%
\begingroup
\let\@elt\UDptelt
\xdef#1{\cl@@ckpt}%
\endgroup
}%

%% Patch \***@writebookmark to also take \HyperDestNameFilter
%% into account:
\@ifpackageloaded{bookmark}{%
\renewcommand*{\***@writebookmark}[5]{%
\ifnum#4>\***@depth\relax
\else
\def\***@type{#5}%
\ifx\***@type\***@bookmarkstype
\begingroup
\***@numbered
\let\numberline\***@numberline
\let\partnumberline\***@numberline
\let\chapternumberline\***@numberline
\else
\let\numberline\@gobble
\let\partnumberline\@gobble
\let\chapternumberline\@gobble
\fi
%%% !!! line changed - \HyperDestNameFilter{...} added.
\bookmark[level=#4,dest={\HyperDestNameFilter{#3}}]{#2}%
\endgroup
\fi
\fi
}%
}{%
\renewcommand*\***@writebookmark[5]{%
\ifx\WriteBookmarks\relax%
\else
\ifnum#4>\***@bookmarksdepth\relax
\else
\@@writetorep{#1}{#2}{\HyperDestNameFilter{#3}}{#4}{#5}%
\fi
\fi
}%
}%

%% Patch hyperref' \addcontentsline to take \HyperDestNameFilter
%% into account:
\renewcommand*\addcontentsline[3]{% toc extension, type, tag
\begingroup
\let\label\@gobble
\ifx\@currentHref\@empty
\***@Warning{%
No destination for bookmark of \string\addcontentsline,%
\MessageBreak destination is added%
}%
\phantomsection
\fi
\expandafter\ifx\csname toclevel@#2\endcsname\relax
\begingroup
\def\***@tempa{#1}%
\ifx\***@tempa\***@bookmarkstype
\***@WarningNoLine{%
bookmark level for unknown #2 defaults to 0%
}%
\else
\***@Info{bookmark level for unknown #2 defaults to 0}%
\fi
\endgroup
\expandafter\gdef\csname toclevel@#2\endcsname{0}%
\fi
\edef\***@toclevel{\csname toclevel@#2\endcsname}%
\***@writebookmark{\csname the#2\endcsname}%
{#3}%
{\@currentHref}%
{\***@toclevel}%
{#1}%
\***@verbose
\def\***@tempa{#3}%
\@***@sanitize\***@tempa
\typeout{pdftex: bookmark at \the\inputlineno: %
{\csname the#2\endcsname}%
{\***@tempa}%
{\@currentHref}%
{\***@toclevel}%
{#1}%
}%
\fi
\addtocontents{#1}{%
%%% !!! line changed - \HyperDestNameFilter{...} added.
\protect\contentsline{#2}{#3}{\thepage}%
{\HyperDestNameFilter{\@currentHref}}%
}%
\endgroup
}

\makeatother

\begin{filecontents*}{UDExam}
\section[Exam (sheet \examcountersequence)]%
{\texorpdfstring{Exam}{Exam (sheet \examcountersequence)}}
That's the test/exam.
The value of \texttt{\string\examcountersequence} is \examcountersequence.
\subsection{some exercise}\label{\HyperDestNameFilter{some exercise}}%
This is an exercise.
\subsection{other exercise}
This is another exercise. Please use the result of exercise
\ref{\HyperDestNameFilter{some exercise}}.
\end{filecontents*}

\begin{document}
\pagenumbering{roman}
\tableofcontents
\cleardoublepage
\pagenumbering{arabic}

\begingroup
\UDckpttomacroglobal{\UDResetCounters}%

\newcommand\examcountersequence{0}
\loop
\edef\examcountersequence{\number\numexpr\examcountersequence+1\relax}%
\edef\HyperDestNameFilter##1{Sheet.\examcountersequence.##1}%
\UDResetCounters
\input{UDExam}%
\cleardoublepage
\ifnum \examcountersequence<10 \repeat
\endgroup

\end{document}
Alan Munn
2011-05-17 15:28:21 UTC
Permalink
Post by GL
The fact is that it's obviously more satisfying to finally get one
single pdf file to print out, than 267 files...
If you've ever tried to get a printer to staple every n-th page of a
single large document, you might appreciate having 267 files.

All my printing is done to a printer/copier, so collating and stapling
is done via the print job. Under this setup, having one big file is
simply crazy.

Alan
Ulrich D i e z
2011-05-17 18:56:13 UTC
Permalink
Post by Alan Munn
Post by GL
The fact is that it's obviously more satisfying to finally get one
single pdf file to print out, than 267 files...
If you've ever tried to get a printer to staple every n-th page of a
single large document, you might appreciate having 267 files.
All my printing is done to a printer/copier, so collating and stapling
is done via the print job. Under this setup, having one big file is
simply crazy.
I think it is a matter of taste and workflow.

Assume you need N copies. Each copy has P pages.

I think there are situations where writing a script for
printing N files with P pages per file is not much harder
than writing a script for a loop which from L := 1 to N
per printjob prints from a big file the pages ((L-1)*P+1) to (L*P) .

Ulrich
Alan Munn
2011-05-17 19:22:39 UTC
Permalink
Post by Ulrich D i e z
Post by Alan Munn
Post by GL
The fact is that it's obviously more satisfying to finally get one
single pdf file to print out, than 267 files...
If you've ever tried to get a printer to staple every n-th page of a
single large document, you might appreciate having 267 files.
All my printing is done to a printer/copier, so collating and stapling
is done via the print job. Under this setup, having one big file is
simply crazy.
I think it is a matter of taste and workflow.
Assume you need N copies. Each copy has P pages.
I think there are situations where writing a script for
printing N files with P pages per file is not much harder
than writing a script for a loop which from L := 1 to N
per printjob prints from a big file the pages ((L-1)*P+1) to (L*P) .
Sure, but I was replying to the "you get one single pdf file to print
out". Either way, you need N print jobs, not one, so having one big
file isn't necessarily an advantage.

Alan
Ulrich D i e z
2011-05-19 00:14:39 UTC
Permalink
Post by Alan Munn
Post by Ulrich D i e z
Post by Alan Munn
Post by GL
The fact is that it's obviously more satisfying to finally get one
single pdf file to print out, than 267 files...
If you've ever tried to get a printer to staple every n-th page of a
single large document, you might appreciate having 267 files.
All my printing is done to a printer/copier, so collating and stapling
is done via the print job. Under this setup, having one big file is
simply crazy.
I think it is a matter of taste and workflow.
Assume you need N copies. Each copy has P pages.
I think there are situations where writing a script for
printing N files with P pages per file is not much harder
than writing a script for a loop which from L := 1 to N
per printjob prints from a big file the pages ((L-1)*P+1) to (L*P) .
Sure, but I was replying to the "you get one single pdf file to print
out". Either way, you need N print jobs, not one, so having one big
file isn't necessarily an advantage.
If it is crazy and not an advantage, then it is challenging and
tempting. If it is challenging and tempting, then accomplishing
it is more satisfying. ;-)
(To be honest, there are matters in life which correlate in a
way which is a mystery to me.)


In case stapling is obsolete, e.g., because each drawing-up
of the document in question fits on one sheet of paper, a
single print job on a big file might be ok.

A few times I saw people printing many copies of a two-side
document consisting of exactly four A4-pages on a single
A3-sheet per copy. Another machine folded the A3-sheets
to A4. Each time the order in which the four pages were
printed on the A3-sheet was wrong at first and the print-job
needed to be aborted.

In case something goes wrong during the print job, resuming
a print job of a big file might be more tedious than aborting
and restarting a print job of a small (portion of a) file.

Ulrich

Continue reading on narkive:
Loading...