4

Suppose that we need to change margins. This cannot be done only by changing \hsize and \vsize, because of the default offset of 1in. There is a possibility to change \hoffset and \voffset directly, but this becomes cumbersome. Is there a more universal solution, using output routine, or some other trick? Also, how to change left offset if the page has even number (for two-pages design)?

5
  • Are you aware of geometry package? – user11232 Oct 2 '15 at 4:55
  • @HarishKumar: yes, but it is interesting to know how this stuff is done. What approach does geometry use? Is it a proper approach in comparison with others? – Igor Liferenko Oct 2 '15 at 5:21
  • What do you mean by “more universal”? – egreg Oct 2 '15 at 8:15
  • By universal I mean that it should make as little consideration about other parameters as possible. – Igor Liferenko Oct 2 '15 at 8:20
  • 1
    @IgorLiferenko Using \voffset and \hoffset takes nothing else under consideration. – egreg Oct 2 '15 at 8:22
3

Is there a more universal solution, using output routine, or some other trick?

For plain TeX, the only "more universal" that I know is the OPmac macros, for example:

\input opmac
\margins/2 a5 (1,1,1,1.4)cm % A5 paper + 1cm margins in two-pages design

In this case, the declared margins are those of the odd pages. The margins of the even pages are just mirrored accordingly. Run texdoc opmac and see section 16, or go the OPmac site for more information.

For LaTeX, you can touch the low level lengths that you can see with the package layout as \hoffset, or as more "universal" (kindly, simple, easy) way, deal with some of the packages of the topic geometry in CTAN, as typearea,anysize, or why not, the ubicuous geometry.

To know that approaches each package, run texdoc <package>. In the case of geometry it is a proper approach as usually it work and there are a nice documentation. With other packages may be you will be less lucky, but you always can run texdoc <package>.sty (now with the extension) and see the source code to understand which methods have been used.

how to change left offset if the page has even number (for two-pages design)?

In LaTeX, use the \layout command (of the package layout) in the document environment!

You will see that in a twoside article \hoffset is always 0pt and it is the same command in odd/even pages. But you but can change \oddsidemargin and \evensidemargin.

In plain TeX you can create these lengths and set \hoffset to odd/even pages conditionally:

% Stolen from a Dan Luecking's answer at comp.text.tex 
\newdimen\oddsidemargin
\newdimen\evensidemargin
\oddsidemargin=.25truein  
\evensidemargin=1truein  
\output={\hoffset=\ifodd\pageno\oddsidemargin\else%
\evensidemargin\fi\plainoutput}

\oddsidemargin=300pt % only to test ...
\evensidemargin=10pt

odd page 
\vfil \break
even page 
\bye
2
  • 1
    Please note the plain-tex -tag. – morbusg Oct 2 '15 at 7:48
  • @morbusg I see... but regarding the comments about geometry I assumed that the goal was a LaTeX approach. – Fran Oct 2 '15 at 8:35
2

The idea of latex format is based on \moveright by value of margin the box of the page when the page is shiped out.

\vsize=5\baselineskip%%

\newdimen\oddsidemargin
\newdimen\evensidemargin

\oddsidemargin=3cm
\evensidemargin=2cm

\catcode`\@11\relax
\def\plainoutput{\shipout\vbox{%
    \ifodd\pageno
          \let\mymargin\oddsidemargin
    \else
          \let\mymargin\evensidemargin
    \fi
    \moveright\mymargin \vbox{%
              \makeheadline\pagebody\makefootline}%
              }%
  \advancepageno
  \ifnum\outputpenalty>-\@MM \else\dosupereject\fi}
\catcode`\@12\relax

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. 

Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. 

\bye 

the original output

\def\plainoutput{\shipout\vbox{\makeheadline\pagebody\makefootline}%
  \advancepageno
  \ifnum\outputpenalty>-\@MM \else\dosupereject\fi}
1

I don't think there is a universal solution, but here's one for horizontal margin that assumes some symmetry (I'm not entirely happy with it, but thought to share anyway):

\catcode`\@=11

% XeTeX doesn't have \pdf[hv]origin (yet?)
\ifdefined\pdfhorigin
\else\csname newdimen\endcsname\pdfhorigin\pdfhorigin=1in \fi
% No \outer allowed inside the skipped conditional (TeX by Topic p. 110)
\ifdefined\pdfvorigin
\else\csname newdimen\endcsname\pdfvorigin\pdfvorigin=1in \fi

\newif\ifspread
\newdimen\bindcorr

% TODO: user could give typeblock size in relation to \pdfpagesize
\def\hmargin{
  \def\next{\hoffset=\dimexpr\dimen@-\pdfhorigin
            \hsize=\dimexpr\pdfpagewidth-2\dimen@
            \ifspread
              \hsize=\dimexpr\hsize+.5\dimen@-\bindcorr
              \dimen@ii=\dimexpr.5\dimen@+\bindcorr-\pdfhorigin
              \def\spreadoutput{\ifodd\pageno\else\hoffset=\dimen@ii
                                \fi\plainoutput}
              \output{\spreadoutput}
            \fi}
  \afterassignment\next\dimen@=}

Usage example:

\pdfpagewidth=6in
\pdfpageheight=9in
\input the_above_codeblock.tex
\spreadtrue
\hmargin 5mm
\input some_text.tex
\bye
1

Thanks to everyone - your answers helped me to obtain the solution. What I did not understand before is that \hoffset and \voffset are looked at only in the output routine. I would like to share what I came up with. Following is the \margins macro, which I put to the format file and use as, e.g., \margins (2.5,1,2,2)/X, where X stands for 1- or 2- sided layout.

\def\margins (#1,#2,#3,#4)/#5 {%
  \hsize = 210 true mm
  \vsize = 297 true mm

  \advance\hsize by -#1 true cm
  \advance\hsize by -#2 true cm

  \advance\vsize by -#3 true cm
  \advance\vsize by -#4 true cm
  \advance\vsize by -.1 true in % as in plain.tex

  \voffset = #3 true cm
  \advance\voffset by -1 true in % annihilate default gap

  \output = {%
    \if 1#5
      \hoffset = #1 true cm
    \else
      \hoffset = \ifodd\pageno #1 true cm \else #2 true cm \fi
    \fi
    \advance\hoffset by -1 true in % annihilate default gap
    \plainoutput
  }%
}
2
  • isn't better if you do this preserving v(h)offset? – touhami Oct 6 '15 at 15:28
  • @touhami Yes, this also works, but I did not like that variant because it is necessary to make additional considerations about the main output routine (because we need to access the box directly - to move it), whereas here we do not have to care about the implementation details of the main output routine. – Igor Liferenko Oct 6 '15 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.