8

I am trying to learn the 'metal' of TeX after 20 years of using higher level packages, such as LaTeX.

In my test document I have an indented block representing simple recipes. I've created this with two macros, for the beginning and end of a recipe:

\def\beginrecipe{
  \par
  \begingroup
  \leftskip=\baselineskip
  \multiply\leftskip by 2
  \rightskip=\leftskip
  \parindent=-\baselineskip
  \parfillskip=0pt plus 1fil
  \reciperule
}
\def\endrecipe{
  \par
  \reciperule
  \endgroup
}

I want the recipe blocks to have horizontal rules at the top and bottom, so I've defined my \reciperule command to be:

\def\reciperule{
  \vskip0.5em\hrule\vskip0.5em
}

In the document this is used something like:

\beginrecipe
{\bf Blonde roux}

2 tbsp of butter.

2 tbsp of flour.

Melt the butter in a pan and add the flour.

Cook the flour without browning for 2 minutes, stirring with a whisk.
\endrecipe

This works well, but the \hrule is too wide. It spans the width of the text-block, I want it to just fill the width of the recipe. So it should start \baselineskip in from the left, and extend to \baselineskip from the right.

I've tried to do this with \hskip\baselineskip and using \hrulefill to fill the available space. The problem is \hskip reserves a line worth of height, which is far too much, I want the rule to be thin.

Can I either indent an \hrule (I know I can set its width, so this would work), or can I get \hskip, \hrulefill, etc, to have a specified height?

Or is there an easier way to do the whole thing (that doesn't use a package beyond Plain TeX)?

4
  • 1
    Could you add a minimal example to play with?
    – egreg
    Dec 6, 2013 at 15:47
  • Yes, just added an example of it, in use. A full minimal example file is at: gist.github.com/idmillington/7827067
    – Ian
    Dec 6, 2013 at 15:55
  • Try \nointerlineskip before and after the rule made with \hrulefill. Dec 6, 2013 at 15:56
  • \halign is your friend my friend
    – doed
    Dec 6, 2013 at 15:59

2 Answers 2

7

You have to \moveright a box with a rule in it, but also to watch out against page breaks before the rule

\def\beginrecipe{
  \par
  \begingroup
  \leftskip=\baselineskip
  \multiply\leftskip by 2
  \rightskip=\leftskip
  \parindent=-\baselineskip
  \parfillskip=0pt plus 1fil
  \nobreak
  \reciperule
}
\def\endrecipe{
  \par\nobreak
  \reciperule
  \endgroup
}
\def\reciperule{
  \nointerlineskip
  \vskip0.5em
  \moveright\baselineskip\vbox{
    \advance\hsize-3\baselineskip
    \hrule width \hsize
  }
  \nointerlineskip
  \nobreak
  \vskip0.5em
}

\beginrecipe
{\bf Blonde roux}

2 tbsp of butter.

2 tbsp of flour.

Melt the butter in a pan and add the flour.

Cook the flour without browning for 2 minutes, stirring with a whisk.
Cook the flour without browning for 2 minutes, stirring with a whisk.
\endrecipe

\bye

enter image description here

1
  • Perfect drop in replacement, thanks @egreg, and --even better-- understandable!
    – Ian
    Dec 6, 2013 at 16:21
5

Please always post complete documents not fragments.

You either need to use a rule within a paragraph so it automatically obeys the paragraph settings like \leftskip or you need to move it across by \leftskip "by hand".

This shows the original and both approaches (which have different effects on vertical space)

update: I just noticed you (somewhat strangely?) have a negative parindent If you want the rule to line up with the text you will need to change the \noindent to \indent so it is similarly moved left.

enter image description here

\def\beginrecipe{
  \par
  \begingroup
  \leftskip=\baselineskip
  \multiply\leftskip by 2
  \rightskip=\leftskip
  \parindent=-\baselineskip
  \parfillskip=0pt plus 1fil
  \reciperule
  \reciperulea
  \reciperuleb
}
\def\endrecipe{
  \par
  \reciperule
  \reciperulea
  \reciperuleb
  \endgroup
}

I want the recipe blocks to have horizontal rules at the top and bottom, so I've defined my reciperule command to be:

\def\reciperule{
  \vskip0.5em\hrule\vskip0.5em
}


\def\reciperulea{
  \vskip0.5em\noindent\hrulefill\hbox{}\par\vskip0.5em
}
\def\reciperuleb{
  \vskip0.5em
   \dimen0\hsize
   \advance\dimen0-\leftskip
   \advance\dimen0-\rightskip
   \moveright\leftskip\vbox{\hrule width\dimen0}
}

In the document this is used something like:

\beginrecipe
{\bf Blonde roux}

2 tbsp of butter.

2 tbsp of flour.

Melt the butter in a pan and add the flour.

Cook the flour without browning for 2 minutes, stirring with a whisk.
\endrecipe

\bye
2
  • Thanks for the tip on full documents. I'll do that next time, for sure. The negative par indent is so that the follow on lines of a step in a recipe is indented in. So it is easy to see the first line of a new step. Using your reciperuleb approach I still get the funky spacing, egreg's answer tweaks adds the extra incantations, so I'll accept that. But thanks for the help!
    – Ian
    Dec 6, 2013 at 16:20
  • 2
    @Ian It is better to use \hangindent (or \hang) or plain tex \item to get that. Dec 6, 2013 at 16:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .