% \iffalse meta-comment % % gridset.dtx % %% Copyright (C) 2008-2020 Markus Kohm %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3c %% 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.3c or later is part of all distributions of LaTeX %% version 2005/12/01 or later. %% %% This work has the LPPL maintenance status "maintained". %% %% The author and current maintainer of this work is %% Markus Kohm . %% %% This work consists of the files gridset.dtx and README.md. %% %% Important Recommendation: %% The LPPL requires that distributions of the Work contain all the files of %% the Work (see ``Important Recommendations'' at lppl.txt). %% % %<*dtx> \def\FmtName{LaTeX2e} \ifx\FmtName\fmtname % Give me the package or the documentation \ifnum \catcode`\@=12\relax % Give me the documentation \ProvidesFile{gridset.dtx} % %<*dtx|package|example> %\ProvidesPackage{gridset} %\ProvidesFile{gridsetexample.tex} [2020-02-12 v0.3 grid - a.k.a. in-register - setting] % %<*dtx> \documentclass{ltxdoc} \begin{document} \RecordChanges \GetFileInfo{gridset.dtx} \DocInput{gridset.dtx} % %<*dtx> \expandafter\expandafter\expandafter\enddocument \fi \else % Make the package \def\batchfile{gridset.dtx} \let\batchendinput\endinput % %<*ins> %\def\batchfile{gridset.ins} \input docstrip.tex \keepsilent \askforoverwritefalse \usedir{tex/latex/gridset} \preamble IMPORTANT NOTE: This is a generated file and you are not allowed to distribute it without the source ot the work. See below about more informations about the files the work consists of. \endpreamble \generate{% \file{gridset.ins}{\from{gridset.dtx}{ins}}% \file{gridset.sty}{\from{gridset.dtx}{package}}% \file{gridsetexample.tex}{\from{gridset.dtx}{example}}% } \ifToplevel{% \Msg{*********************************************************************} \Msg{*} \Msg{* gridset} \Msg{* =======} \Msg{*} \Msg{* THIS IS AN ALPHA VERSION!} \Msg{* DON'T USE IT ONLY TEST IT!} \Msg{*} \Msg{* To finish the installation run} \Msg{* \space\space latex gridset.dtx} \Msg{* or} \Msg{* \space\space pdflatex gridset.dtx} \Msg{* and then copy} \Msg{* \space\space gridset.sty to .../tex/latex/gridset/} \Msg{* \space\space gridset.dvi or gridset.pdf to .../doc/latex/gridset/} \Msg{* \space\space gridset.dtx and README to .../source/latex/gridset/} \Msg{* where .../ is your local TDS tree.} \Msg{* On some systems you'll get the local TDS tree using:} \Msg{* \space\space kpsewhich -var-value=TEXMFLOCAL} \Msg{*} \Msg{*********************************************************************} } % %<*dtx> \fi \csname fi\endcsname \csname batchendinput\endcsname % % \fi ^^A meta-comment % % \title{Semi-Manual Grid Setting Using \textsf{gridset}% % \footnote{This is an alpha version! Don't use it! Only test it! There's no % support and everything may change!}% % } % \author{Markus Kohm} % \date{\filedate~\fileversion} % \maketitle % \begin{abstract} % Grid setting\,---\,also known as strict in-register setting\,---\,is % something, that should be done for a lot of documents but is not easy % using \LaTeX{}. Package \textsf{gridset} helps to get the information % needed for grid setting. It does not implement auto grid setting, but % there is a command \cs{vskipnextgrid}, that moves to the next grid % position. This may be enough under some circumstances. In other % circumstances it may fail. So \textsf{gridset} is only one more step for % grid setting not a complete solution. % % \paragraph*{Important Note:} This package should have been never released, % because it was only a very quick implementation of an idea. You should not % use it for any productive purpose. It has been made for testing only. I % would prefer to retire it from any distribution. Nevertheless I know few % persons using the package. So it will be still there but without any % support! % \end{abstract} % \tableofcontents % \section{User Manual} % % \DescribeMacro{\gridinterval}% % This macro contains a number without unit! The number is the distance % between two grid lines in unit `scale points' (sp). You may set it so % another value using, e.g. % \begin{flushleft} % |\newlength{\|\meta{name of your length}|}|\\ % |\setlength{\|\meta{name of your length}|}{|\meta{new length value}|}|\\ % |\newcounter{\|\meta{name of your counter}|}|\\ % |\setcounter{\|\meta{name of your counter}|}{\|\meta{name of your % length}|}|\\ % |\edef\gridinterval{\|\meta{name of your length}|}|\\ % \end{flushleft} % % \DescribeMacro{\gridbase}% % This macro contains an integer number, that represents the y-coordinate of % the upper start of the grid. If you want to change it, just save a position % and \cs{edef} the \cs{gridbase} to the y-pos of that position. % % Most time you don't need to change \cs{gridinterval} and \cs{gridposition}, % because they are initialized to a base line grid at start of first page. % Because of this, it doesn't matter, that changing them is not really user % friendly. % % \DescribeMacro{\SavePos}% % \DescribeMacro{\savepos}% % \cs{SavePos}\marg{unique name} saves informations about the current position % to the \texttt{aux}-file. These informations are read at next \LaTeX{} run % and may be used (see \cs{the\dots} commands below) then. The \meta{unique % name} has to be a position name, that is unique for all saved position % informations of the current document. Note that the command has been renamed % from \cs{savepos} to \cs{SavePos} in release~0.2, because Lua\TeX{} since % 0.85 uses \cs{savepos} as a new primitive. On other engines the old name % \cs{savepos} is still available. % % \DescribeMacro{\vskipnextgrid} % This command moves to the next grid position. To achieve this, a position % information is saved at this and used at next \LaTeX{} run. The used name % of the position information is \texttt{vb!\meta{number of % skip}}. \meta{number of skip} is the number of the current % \cs{vskipnextgrid} usage. Counter \texttt{gridcnt} is used to number the % usage of \cs{vskipnextgrid}. % % \DescribeMacro{\thegridinfo} % \cs{thegridinfo}\marg{name} outputs % \begin{itemize} % \item arabic page number of the named position, % \item grid base, that was valid saving the information of the named % position, % \item grid interval, that was valid saving the information of the named % position, % \item x-coordinate of the named position, % \item y-coordinate of the named position. % \end{itemize} % The coordinates and intervals are numbers without units. The unit is `scale % points' (sp). % % \DescribeMacro{\theposinfo} % \cs{theposinfo}\marg{name} outputs % \begin{itemize} % \item y-coordinate of the named position, % \item grid line number (first is 0) of the next grid position, % \item offset of the next grid position from grid base, % \item distance to the next grid position. % \end{itemize} % The coordinates, offsets and distances are numbers without units. The unit % is `scale points' (sp). % % \DescribeMacro{\theypos} % \cs{theypos}\marg{name} outputs the y-coordinate of the named position. % % % \StopEventually{\PrintIndex\PrintChanges} % % \section{Implementation} % % \iffalse meta-comment %<*package> % \fi ^^A meta-comment % % \begin{macro}{gridset@luaorpdf} % \changes{v0.2}{2017/06/05}{new internal because of Lua\TeX~0.85} % \begin{macro}{\gridset@pageheight} % \changes{v0.2}{2017/06/05}{new internal because of Lua\TeX~0.85} % \begin{macro}{\gridset@pagewidth} % \changes{v0.2}{2017/06/05}{new internal because of Lua\TeX~0.85} % \begin{macro}{\gridset@savepos} % \changes{v0.2}{2017/06/05}{new internal because of Lua\TeX~0.85} % \begin{macro}{\gridset@lastxpos} % \changes{v0.2}{2017/06/05}{new internal because of Lua\TeX~0.85} % \begin{macro}{\gridset@lastypos} % \changes{v0.2}{2017/06/05}{new internal because of Lua\TeX~0.85} % We need some locals because Lua\TeX{} changed the names of several % primitives inherited from PDF\TeX. % \begin{macrocode} \newcommand*{\gridset@luaorpdf}[1]{% \expandafter\newcommand\csname gridset@#1\endcsname{}% \ifcsname pdf#1\endcsname \expandafter\let\csname gridset@#1\expandafter\endcsname \csname pdf#1\endcsname \else \ifcsname #1\endcsname \expandafter\let\csname gridset@#1\expandafter\endcsname \csname #1\endcsname \else \PackageError{gridset}{% neither \expandafter\string\csname #1\endcsname\space nor \xpandafter\string\csname pdf#1\endcsname\space defined% }{This package needs either PDFTeX or LuaTeX or XeTeX.}% \fi \fi } \gridset@luaorpdf{pageheight} \gridset@luaorpdf{pagewidth} \gridset@luaorpdf{savepos} \gridset@luaorpdf{lastxpos} \gridset@luaorpdf{lastypos} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\gridbase} % \changes{v0.2}{2017/06/05}{prepared for Lua\TeX~0.85} % \begin{macro}{\gridinterval} % \changes{v0.2}{2017/06/05}{prepared for Lua\TeX~0.85} % These contain the grid information. \cs{gridbase} is a integer number % representing the absolute y coordinate of the upper end of the % grid relative to the same reference point \cs{pdfsavepos} % uses. \cs{gridinterval} is a integer number representing the distance of % two grid lines. The unit is `scaled point' (sp) both time. % \begin{macrocode} \newcommand*{\gridbase}{} \newcommand*{\gridinterval}{} % \end{macrocode} % \cs{gridbase} and \cs{gridinterval} need to be initialized at the start of % the first page (fixme: shouldn't this be done at the start of every % page?). We use this occasion to also initialize \cs{pdfpageheight} and % \cs{pdfpagewidth} if this hasn't been done already. % \begin{macrocode} \AtBeginDocument{% \ifdim\gridset@pageheight=\z@ \gridset@pageheight=\paperheight \fi \ifdim\gridset@pagewidth=\z@ \gridset@pagewidth=\paperwidth \fi \begingroup \@tempdima=\dimexpr \gridset@pageheight - \topmargin - 1in - \headheight - \headsep - \topskip \relax \@tempcnta=\@tempdima \xdef\gridbase{\the\@tempcnta}% \@tempcnta=\baselineskip \xdef\gridinterval{\the\@tempcnta}% \endgroup } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\savepos} % \changes{v0.2}{2017/06/05}{macro renamed} % \begin{macro}{\SavePos} % \changes{v0.2}{2017/06/05}{new name} % \changes{v0.2}{2017/06/05}{prepared for Lua\TeX~0.85} % Save current position on the page to the \texttt{aux}-file. The argument % is a unique name for the position. The saved informations are: % \begin{itemize} % \item the name of the position, % \item the arabic page number of the page with the position, % \item the grid base, that was valid for this position, % \item the grid interval, that was valid for this position, % \item the x-coordinate of the absolute position, % \item the y-coordinate of the absolute position. % \end{itemize} % \begin{macrocode} \newcommand*{\SavePos}[1]{% \begingroup \gridset@savepos \protected@write\@auxout{}{% \protect\newpos{#1}{\the\count\z@}{\gridbase}{\gridinterval}{% \noexpand\number\gridset@lastxpos }{% \noexpand\number\gridset@lastypos }% }% \endgroup } \ifx\savepos\gridset@savepos \PackageInfo{gridset}{LuaTeX detected.\MessageBreak Note, gridset command is \string\SavePos\MessageBreak but not \string\savepos, which is\MessageBreak a LuaTeX primitive }% \else \PackageInfo{gridset}{\string\savepos\space defined as an alias of \string\SavePos}% \newcommand*{\savepos}{\SavePos}% \fi % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\newpos} % This is the command, that has been written to the \texttt{aux}-file. % Reading the \texttt{aux}-file it defines several position dependant macros % to store the position information. Reading the \texttt{aux}-file while % \cs{begin{document}} a double definition test is done. Reading the % \texttt{aux}-file while \cs{end{document}} a test is done, if the position % has been changed and notes the user about needed additional \LaTeX{} runs. % (fixme: shouldn't the test be done with the x- and the y-coordinate % instead of the vskip only?) % The defined macros are: % \begin{description} % \item[\cs{pos@\meta{position name}@page}] the arabic page number of the % position % \item[\cs{pos@\meta{position name}@base}] the valid grid base while % saving the position % \item[\cs{pos@\meta{position name}@interval}] the valid grid interval % while saving the position % \item[\cs{pos@\meta{position name}@x}] the x-coordinate of the position % \item[\cs{pos@\meta{position name}@y}] the y-coordinate of the postion % \item[\cs{pos@\meta{position name}@line}] the number of the next grid line % for the position (first grid line has number 0) % \item[\cs{pos@\meta{position name}@offset}] distance of the next grid line % from the grid base % \item[\cs{pos@\meta{position name}@vskip}] distance to the next grid line % for the position % \end{description} % All values are integers. The unit to all values is `scaled points' % (sp). See \cs{pdfsavepos} at the pdf\TeX{} user manual for more % information. % \begin{macrocode} \newcommand*{\newpos}[6]{% \grid@unique@test{#1}{#2}% \expandafter\global\@namedef{pos@#1@page}{#2}% \expandafter\global\@namedef{pos@#1@base}{#3}% \expandafter\global\@namedef{pos@#1@interval}{#4}% \expandafter\global\@namedef{pos@#1@x}{#5}% \expandafter\global\@namedef{pos@#1@y}{#6}% \begingroup \@tempcnta=\numexpr \@nameuse{pos@#1@base} - \@nameuse{pos@#1@y}\relax \@tempcnta=\numexpr \@tempcnta + \@nameuse{pos@#1@interval} - 1\relax \divide\@tempcnta by\@nameuse{pos@#1@interval}\relax \expandafter\xdef\csname pos@#1@line\endcsname{\the\@tempcnta}% \@tempcnta=\numexpr \@tempcnta * \@nameuse{pos@#1@interval}\relax \expandafter\xdef\csname pos@#1@offset\endcsname{\the\@tempcnta}% \@tempcnta=\numexpr \@nameuse{pos@#1@y} - ( \@nameuse{pos@#1@base} - \@tempcnta )\relax \expandafter\let\expandafter\@tempa\csname pos@#1@vskip\endcsname% \expandafter\xdef\csname pos@#1@vskip\endcsname{\the\@tempcnta}% \expandafter\ifx\csname pos@#1@vskip\endcsname\@tempa\else \grid@ReRunMessage \fi \endgroup } % \end{macrocode} % \begin{macro}{\grid@unique@test} % A very simple test to warn if a position name isn't unique. % \begin{macrocode} \newcommand*{\grid@unique@test}[2]{% \expandafter\ifx\csname pos@#1@page\endcsname\relax\else \PackageError{gridset}{position `#1' is not unique.\@gobble}{% You have used the position name `#1' you are using on page `#2'\MessageBreak already on page `\csname pos@#1@page\endcsname'.\MessageBreak You should stop processing, remove the aux-files and correct the names.\MessageBreak If you'd continue, this will result in grid position failures,\MessageBreak that won't be reported!}% \fi } \AtBeginDocument{% \global\let\grid@unique@test\@gobble } % \end{macrocode} % \end{macro} % \begin{macro}{\grid@ReRunMessage} % The change test will be done for each \cs{newpos} but one user information % at the end of the document should be enough. So we use a message macro, % that destroys itself after first usage. % \begin{macrocode} \newcommand*\grid@ReRunMessage{} \AtBeginDocument{% \renewcommand*\grid@ReRunMessage{% \PackageWarningNoLine{gridset}{Grid position labels may have changed.\MessageBreak Rerun to get grid positions right}% \global\let\grid@ReRunMessage\relax }% } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\vskipnextgrid} % \begin{macro}{gridcnt} % Move to next grid position. The counter \texttt{gridcnt} is used to give % every move to position a unique position name. The names are % `\texttt{vp!\meta{number of the move to position}}'. You may use this to % get informations e.g. about the last move to position. % \begin{macrocode} \newcounter{gridcnt} \newcommand*{\vskipnextgrid}{% \begingroup \stepcounter{gridcnt}\edef\@tempa{vp!\thegridcnt}% \ifvmode % \end{macrocode} % \cs{pdfsavepos} in vertical mode is a problem, because the base line % alignment will be done at least at paragraph breaking. Because of this, % we have to leave the vertical mode and do it then. But remark: If you % change the base line skip e.g. changing the font size, the next line would % not be grid aligned! % \begin{macrocode} \leavevmode\SavePos{\@tempa}% \expandafter\ifx\csname pos@\@tempa @vskip\endcsname\relax \else \expandafter\ifnum \csname pos@\@tempa @vskip\endcsname =\z@\else \PackageInfo{gridset}{% vmode \string\vskip\csname pos@\@tempa @vskip\endcsname sp% }% \vskip -\parskip\vskip -\baselineskip \expandafter\vskip\csname pos@\@tempa @vskip\endcsname sp\relax \fi \fi \else % \end{macrocode} % \cs{pdfsavepos} in horizontal mode is a problem too, because we have to % enter the vertical mode to do vertical skips. Because of this, the remark % is the same like the vertical mode remark. % \begin{macrocode} \parskip=\z@ \SavePos{vp!\thegridcnt}% \expandafter\ifx\csname pos@\@tempa @vskip\endcsname\relax \else \expandafter\ifnum \csname pos@\@tempa @vskip\endcsname =\z@\else \PackageInfo{gridset}{% hmode \string\vskip\csname pos@\@tempa @vskip\endcsname sp% }% \vskip \dimexpr -\baselineskip + \csname pos@\@tempa @vskip\endcsname sp\relax % \end{macrocode} % \changes{v0.3}{2020/02/12}{support for twocolumn mode} % In twocolumn mode we have to take care that in the second column we reduce % the horizontal movement by the width of the first column plus the column % separation. % Note: This may fail, because the column information may be wrong % outside the output routine. Maybe we should add this information to % \cs{SavePos} or correct the x-pos there. % \begin{macrocode} \leavevmode \if@twoside \expandafter\ifodd\csname pos@\@tempa @page\endcsname\relax \hskip \dimexpr -1in - \oddsidemargin - \parindent \if@twocolumn\if@firstcolumn\else - \columnwidth - \columnsep \fi\fi + \csname pos@\@tempa @x\endcsname sp\relax \else \hskip \dimexpr -1in - \evensidemargin - \parindent \if@twocolumn\if@firstcolumn\else - \columnwidth - \columnsep \fi\fi + \csname pos@\@tempa @x\endcsname sp\relax \fi \else \hskip \dimexpr -1in - \oddsidemargin - \parindent \if@twocolumn\if@firstcolumn\else - \columnwidth - \columnsep \fi\fi + \csname pos@\@tempa @x\endcsname sp\relax \fi \fi \fi \fi \endgroup } % \end{macrocode} % (fixme: A better solution would be to first move and then set the % position. But that solution needs some more tests and maybe some more % ideas, because after moving the position is on grid and so the saved x-pos % would be on grid.) % \end{macro} % \end{macro} % % \begin{macro}{\thegridinfo} % \begin{macro}{\theposinfo} % \begin{macro}{\theypos} % Some informations about the grid (valid for a position) or the position. % \begin{macrocode} \newcommand*{\thegridinfo}[1]{% page=\@nameuse{pos@#1@page}, base=\@nameuse{pos@#1@base}, interval=\@nameuse{pos@#1@interval}, x=\@nameuse{pos@#1@x}, y=\@nameuse{pos@#1@y}% } \newcommand*{\theposinfo}[1]{% y=\@nameuse{pos@#1@y}, gridline=\@nameuse{pos@#1@line}, gridoffset=\@nameuse{pos@#1@offset}, movedown=\@nameuse{pos@#1@vskip}% } \newcommand*{\theypos}[1]{\@nameuse{pos@#1@y}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \iffalse meta-comment %<*FALSE> \csname endinput\endcsname % % % \fi % % \section{Example} % % You may try the following example document. You have to do several \LaTeX{} % runs until no new rerun warning occurs. % \iffalse meta-comment %<*example> % \fi % \begin{macrocode} \documentclass[a4paper,12pt]{article} \usepackage{gridset} \usepackage{blindtext} \raggedbottom \pagestyle{myheadings} \begin{document} \markright{gridbase=\gridbase, gridinterval=\gridinterval\ without move down}% \newcounter{Zeile}% \makeatletter \@whilenum \value{Zeile}<40\do {% \stepcounter{Zeile}% \theZeile. Zeile: \SavePos{\thepage.\theZeile}\thegridinfo{\thepage.\theZeile}\par }% \makeatother \clearpage \setcounter{Zeile}{0} \makeatletter \@whilenum \value{Zeile}<20\do {% \stepcounter{Zeile}% \theZeile. Zeile: \SavePos{\thepage.\theZeile}\theposinfo{\thepage.\theZeile}\par }% \makeatother \clearpage \parskip=.5\baselineskip \setcounter{Zeile}{0} \makeatletter \@whilenum \value{Zeile}<20\do {% \stepcounter{Zeile}% \theZeile. Zeile: \SavePos{\thepage.\theZeile}\theposinfo{\thepage.\theZeile}\par }% \makeatother \clearpage \markright{gridbase=\gridbase, gridinterval=\gridinterval\ with real move down at vmode}% \parskip=.5\baselineskip \setcounter{Zeile}{0} \makeatletter \@whilenum \value{Zeile}<25\do {% \stepcounter{Zeile}% \vskipnextgrid\theZeile. Zeile: \theposinfo{vp!\thegridcnt}\par }% \makeatother \clearpage \markright{gridbase=\gridbase, gridinterval=\gridinterval\ with real move down at hmode}% \parskip=.5\baselineskip \setcounter{Zeile}{0} \makeatletter \@whilenum \value{Zeile}<25\do {% \stepcounter{Zeile}% \theZeile. Zeile: \vskipnextgrid\theposinfo{vp!\thegridcnt}\par }% \makeatother \clearpage \parskip=0pt \blindtext \begin{itemize} \item Test \item Test \end{itemize} \vskipnextgrid\theposinfo{vp!\thegridcnt}\blindtext \end{document} % \end{macrocode} % \iffalse meta-comment % % \fi % % \Finale % \endinput % % end of `gridset.dtx' % %%% Local Variables: %%% mode: docTeX %%% TeX-master: t %%% End: