% cropmarks.tex
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Petr Olsak  <petr@olsak.net>                           Jun. 2022

% This macro adds crop-marks to PDF documents and creates new PDF ouput.
% See the end of this file for usage and more information.

\newdimen\mlenght  \newdimen\mthick   
\newdimen\gap      \newdimen\lgap
\newdimen\hmargin  \newdimen\vmargin
\newdimen\overlap
\newcount\tmpnum
\newcount\hmiddle  \newcount\vmiddle
\newdimen\sheetw   \newdimen\sheeth

%% Defaults:

\hmargin=10mm  % added left+right margins from the document border to the sheet border   
\vmargin=10mm  % added top+bottom margins from the document border to the sheet border   
\mlenght=5mm   % lenght of the crop-mark abscisses
\gap=2mm       % distance of crop-mark abscisses from the document corner
\mthick=.2pt   % thickness of the crop-mark abscisses
\overlap=0mm   % document borders can exceed to the crop area by \overlap
\hmiddle=1     % number of equidistant middle marks in left+right margins
\vmiddle=1     % number of equidistant middle marks in top+bottom margins

\def\document{name}
\def\info{}

\newbox\hrul \newbox\vrul

\def\initboxes{
   \setbox\hrul=\hbox{\vrule width\mlenght height.5\mthick depth.5\mthick}
   \setbox\vrul=\hbox to0pt{\hss\vrule width\mthick  height\mlenght\hss}
   \ht\hrul=0pt \dp\hrul=0pt
   \lgap=\gap  \advance\lgap by\mlenght
}
\def\cropLT{\vbox to0pt{\vss\llap{\copy\hrul\kern\gap\raise\gap\copy\vrul}}}
\def\cropRT{\vbox to0pt{\vss\rlap{\raise\gap\copy\vrul\kern\gap\copy\hrul}}}
\def\cropLB{\vbox to0pt{\llap{\copy\hrul\kern\gap\lower\lgap\copy\vrul}\vss}}
\def\cropRB{\vbox to0pt{\rlap{\lower\lgap\copy\vrul\kern\gap\copy\hrul}\vss}}
\def\middleT{\vbox to0pt{\vss\copy\vrul\kern\gap}}
\def\middleB{\vbox to0pt{\kern\gap\copy\vrul\vss}}
\def\middleL{\llap{\copy\hrul\kern\gap}}
\def\middleR{\rlap{\kern\gap\copy\hrul}}
\def\middleV#1#2{\setbox0=\hbox to#2{#1\kern\gap\hlin#1\hlin\kern\gap#1}%
   \vbox to0pt{\vss\box0\vss}}
\def\middleH#1#2{\setbox0=\vbox to#2{#1\kern\gap\vlin#1\vlin\kern\gap#1}%
   \hbox to0pt{\hss\box0\hss}}
\def\hlin{\leaders\vrule height.5\mthick depth.5\mthick\hfil}
\def\vlin{\leaders\hrule width\mthick\vfil}
\def\middledim{\csname mc?h\the\tmpnum\endcsname}

% \cropmarks{box} 
% creates a dimension-less crop marks around the box and prints the box with them:

\def\cropmarks#1{%
   \vbox{\offinterlineskip 
         \setbox0=\hbox{\kern-\overlap#1\kern-\overlap}
         \dimen0=\wd0 \dimen1=\ht0 \advance\dimen1 by\dp0 \advance\dimen1 by-2\overlap
         \kern-\overlap
         \box0
         \kern-\overlap
         \vbox to0pt{
            \kern-\dimen1
            \ifx\info\empty \else
               \vbox to0pt{\vss\hbox{\quad\strut\info}\kern\gap}\fi
            \hbox to\dimen0{\cropLT\hss \vmiddleloop\middleT \cropRT}
            \vss \tmpnum=0
            \loop \ifnum\tmpnum<\hmiddle
                  \advance\tmpnum by1
                  \hbox to\dimen0
                     \ifcsname mc?h\the\tmpnum\endcsname
                        {\middleH\middleL\middledim \hss \middleH\middleR\middledim}%  
                     \else {\middleL\hss\middleR}\fi
                  \vss \repeat
            \hbox to\dimen0{\cropLB\hss\vmiddleloop\middleB \cropRB}
         }
}}
\def\vmiddleloop#1{\tmpnum=0
   \loop
   \ifnum\tmpnum<\vmiddle
      \advance\tmpnum by1
      \ifcsname mc?v\the\tmpnum\endcsname \middleV#1{\csname mc?v\the\tmpnum\endcsname}%
      \else #1\fi
      \hss
      \repeat
}
\def\docropmarks{%
   \initboxes
   \setbox0=\hbox{\pdfximage {\document.pdf}\pdfrefximage\pdflastximage}
   \pdfpagewidth=\dimexpr\wd0-2\overlap+2\hmargin  \relax
   \pdfpageheight=\dimexpr\ht0+\dp0-2\overlap+2\vmargin \relax
   \hoffset=\hmargin \advance\hoffset by-\pdfhorigin
   \voffset=\vmargin \advance\voffset by-\pdfvorigin
   \ifdim\sheetw=0pt \else 
      \ifdim\sheetw<\pdfpagewidth  \warn{Sheet size is too small, ignored}\else
      \ifdim\sheeth<\pdfpageheight \warn{Sheet size is too small, ignored}\else
         \advance\hoffset by.5\dimexpr \sheetw-\pdfpagewidth \relax
         \advance\voffset by.5\dimexpr \sheeth-\pdfpageheight\relax
         \pdfpagewidth=\sheetw \pdfpageheight=\sheeth 
   \fi\fi\fi 
   %
   \pageno=1
   \shipout\cropmarks{\box0}
   \loop
      \ifnum\pageno<\pdflastximagepages
      \advance\pageno by1
      \shipout\cropmarks
         {\hbox{\pdfximage page\pageno{\document.pdf}\pdfrefximage\pdflastximage}}
      \repeat
   \end
}
\let\\=\undefined % for better elimination of bad command line syntax
\def\warn#1{\wterm{WARNING: #1.}}

\def\sheetsize {\futurelet\next\sheetsizeA}
\def\sheetsizeA {\ifx\next(\expandafter\sheetsizeB \else \expandafter\sheetsizeC \fi} 
\def\sheetsizeB (#1,#2)#3 {\sheetw=#1#3\relax \sheeth=#2#3\relax}
\def\sheetsizeC #1 {\ifcsname sheet:#1\endcsname \csname sheet:#1\endcsname 
                    \else \warn{Unknown sheet type "#1", ignored}\fi}
\def\sheetdecl #1 (#2,#3)#4 {%
   \expandafter\def \csname sheet:#1\endcsname  {\sheetsizeB (#2,#3)#4 }% portrait
   \expandafter\def \csname sheet:#1l\endcsname {\sheetsizeB (#3,#2)#4 }% landscape
} 
\sheetdecl a0  (841,1189)mm
\sheetdecl a1  (594,841)mm
\sheetdecl a2  (420,594)mm
\sheetdecl a3  (297,420)mm
\sheetdecl a4  (210,297)mm
\sheetdecl a5  (148,210)mm
\sheetdecl b0  (1000,1414)mm
\sheetdecl b1  (707,1000)mm
\sheetdecl b2  (500,707)mm
\sheetdecl b3  (353,500)mm
\sheetdecl b4  (250,353)mm
\sheetdecl b5  (176,250)mm
\sheetdecl letter (8.5,11)in

\frenchspacing
\def\othe #1{\ifnum#1<10 0\fi\the#1}
\def\today {\the\year-\othe\month-\othe\day}   % you can re-define this format
\ifx\optexversion\undefined \catcode`\_=12 \fi % names can include _ character

\def\middlecrop #1:#2{\expandafter\def\csname mc?#1\endcsname{#2}}

\endinput


About the cropmarks.tex macro
=============================

This macro adds crop-marks to arbitrary PDF documents. The PDF document can
be created by LaTeX or OpTeX or ConTeXt or something else. Then use
this plain TeX macro for creating additional crop-marks.

Prepare following TeX file. Its name can be crop.tex, for example, but its
name cannot be cropmarks.tex, becuase this is the macro file.

--------------------------------

\input cropmarks

\def\document{name} % the name of the PDF file without extension 
\def\info{}         % info text printed in the top (in crop area) 

\hmargin=10mm  % added left+right margins from the document border to the sheet border   
\vmargin=10mm  % added top+bottom margins from the document border to the sheet border   
\mlenght=5mm   % lenght of the crop-mark abscisses
\gap=2mm       % distance of crop-mark abscisses from the document corner
\mthick=.2pt   % thickness of the crop-mark abscisses
\overlap=0mm   % document borders can exceed to the crop area by \overlap
\hmiddle=1     % number of equidistant middle marks in left+right margins
\vmiddle=1     % number of equidistant middle marks in top+bottom margins

\docropmarks   % reads \document.pdf and creates new PDF file

---------------------------------

and run it by:

   pdftex crop

or

   optex crop

Of course, you can set different values than these default ones mentioned
in the example.

The information text defined in the \info macro can include \document.pdf
(document name), \folio (page number), \today (current date). For example,
you can try:

   \def\info{\tt [\document.pdf] -- \today\ -- page: \folio}

You can run cropmarks without creating the crop file directly from command line:

   pdftex cropmarks '\def\document{name} \docropmarks'

This command reads name.pdf and creates cropmarks.pdf as the output.
You can have your own configuration of mentioned values in cropmaks.cfg file 
and run

   pdftex cropmaks '\input cropmarks.cfg \def\document{name} \docropmarks'

You can use optex instead pdftex, of course.

If you are printing at duplex printer then the pages at front
and back sides must be ovelapping. It means that you must know the real
sheet size used in the printer and the printed material is centered in it.
If this case is true then you can declare \sheetsize (width,height)unit for
example \sheetsize (800,600)mm or you can use predeclared types by
\sheetsize sheet-type, where sheet-type is one of a0, a1, a2, a3, a4, a5,  
a0l, a1l, a2l, a3l, a4l, a5l, b0, b1, b2, b3, b4, b5, b0l, b1l, b2l, b3l,
b4l, b5l, letter, letterl. When \sheetsize is declaed then PDF output
dimensions are set to these values and the input pages including crop marks
are put to the middle of sheet. The declared sheet must have greater or
equal sizes to input page size enlarged by margins for crop marks, otherwise
the \sheetsize declaration is ignored. Default: \sheetsize isn't declared,
i.e. the PDF output dimensions are exacty calculated from input dimensions
enlarged by margins for crop marks.  

If you want to put more pages to one sheet then you have to do this job
first and then you can add cropmarks for whole sheets. Use another software
(or your TeX macro or use OpTeX trick 0088) for creating sheets and create a
new PDF document. Then set appropriate number of middle marks and read this
new document with sheets at input side when you are using cropmarks.tex

The middle marks are only single lines by default (intendend for paper bend
only). Sometimes we need to leave a space for crop area here too. This is
possible by \middlecrop vnum:{dimen} or \middlecrop hnum:{dimen}
declaration. The "h" is declaration for \hmiddle marks (left+right
margins) and "v" for \vmiddle marks (top+bottom margins). The "num" is order
number of given middle mark and dimen is the amout of the space between crop
marks created here (the single-line mark for paper bend is added between
them to the center). For example, you can create "imposition sheets" with 8
pages per sheet shown in the example of the OpTeX trick 0088. See also
https://en.wikipedia.org/wiki/Imposition. Then you can declare:

   \hmiddle=1 \middlecrop h1: {18mm}
   \vmiddle=3 \middlecrop v2: {14mm}

It says that there is single \hmiddle mark which is intended for bend
followed by crop 9mm and there is first and third \vmiddle mark intended for
bend only and second \vmiddle mark is used for bend followed by crop 7mm.
We get something like this:

    _|      |      |_|_|      |      |_

       page   page       page   page

    _                                 _
    _|                               |_
    _|                               |_


       page   page       page   page
    _               _ _               _
     |      |      | | |      |      |


