2

I've got a macro to insert a blank for fill-in-the-blank questions on my tests, but when it is at the beginning of a line, it breaks the paragraph right after the blank and the rest of the question moves down. Everything is working when the blank ends up in the midst or end of a line, though. I can get it to not break to a new paragraph, but I have to put a slashed space before it and I don't like the extra space.

My macro is:

\newcommand{\plongblank}%
     {\hbox to 1.2in {\rule[.1in]{0in}{.15in}%
                 {\hrulefill}}}%

(The rule is a strut to give the students room to write if this falls in a 2nd or later line of the question.)

I found and adapted this answer by egreg (Thanks!) to my needs, but I can't figure out why his works and mine doesn't? I'm guessing it is the penalty and +/- stretch, but I'd really like to know for sure and why.

Here's a MWE for completeness:

\documentclass{article}

\newcommand{\plongblank}%
     {\hbox to 1.2in {\rule[.1in]{0in}{.15in}%
                 {\hrulefill}}}%
\newcommand{\blank}[2][100]{\hfil\penalty#1\hfilneg\rule[.1in]{0in}{.15in}%
                                                   \rule[-3pt]{#2}{0.5pt}}

% commenting this out makes the paragraph break evident
%\setlength{\parindent}{0pt}

\begin{document}

When passing parameters to a function by value, any changes that the function
makes to the parameters
\plongblank{}
%\blank{1.2in}
reflected in the variables passed to the function in the calling function.

\plongblank{}
%\ \plongblank{}
%\blank{1.2in}
describes the functionality in C++ where 2 or more functions share the same
name, and the determination of which function is called is based on the number
and/or type of parameters that are being passed.

\end{document}
3
  • Add \leavevmode before \hbox?
    – egreg
    Feb 20 at 20:58
  • @egreg witchcraft! how'd you know? I want to understand!
    – Craie
    Feb 21 at 0:25
  • I was bitten by the same problem a few years ago, when LaTeX2e didn’t yet exist and I was using plain TeX…
    – egreg
    Feb 21 at 8:58

3 Answers 3

2

TeX puts typesetting objects to a list at each moment and it is working in horizontal (internal), vertical (internal/outer), paragraph (i.e. outer horizontal), math (internal/display) mode at each moment. It is more complicated but for understanding basic principle suppose only horizontal, vertical and paragraph modes. TeX changes current mode using stack and creates a list of typesetting objects in each mode: in horizontal or paragraph mode it creates horizontal list, in vertical mode it creates vertical list. So we have a tree with lists.

At the start of \hbox, TeX opens horizontal (internal) mode and puts the objects from \hbox to horizontal list. At the end of \hbox, TeX closes the horizontal list, creates a box consisting this list, leave the horizontal mode and puts the created box as a single object to the currently created list in "parent" mode. Whenever TeX sees \vbox, it does almost the same but opens and close vertical mode.

TeX starts creating the document in vertical mode. If the vertical mode is current and \indent, \noindent, \leavevmode or individual letter occurs then it opens paragraph mode. If paragraph mode is current and \par or empty line occurs, TeX finalizes paragraph mode: breaks created horizontal list to lines of the paragraph and puts these lines to the vertical list of the "parent" vertical mode. Switching between vertical and paragraph modes is basic principle for creating paragraphs.

Suppose now example: TeX is in vertical mode and sees \hbox{abc} followed by efg followed by empty line. The \hbox{abc} is put to the vertical list as single box and then individual letter e opens the paragraph mode. Empty line finalizes the paragraph mode, creates one line of the paragraph with indentation and efg letters and puts this line to the vertical list of the "parent" vertical mode. We have \hbox{abc} in this vertical list followed by the line <indent>efg. Most important: they are in the vertical list, so they are one above second. Suppose modified example: \leavevmode\hbox{abc}efg. Now TeX first opens paragraph mode and puts the box and the efg to its horizontal list. Important note: they are in the horizontal lists, i.e. they will be in a single line of the paragraph side by side.

Do experiments with this example and try to understand this:

\levevmode % comment it or not
\hbox{abc}
efg
\par

The switching between modes in basic feature of TeX. Unfortunately, is is ignored in most of manuals for beginners.

1
  • Thank you for the detailed explanation! I've read both the TeXbook and Leslie's book, but that was years ago. I've obviously forgotten most of my basics!
    – Craie
    Feb 22 at 15:20
1

Try a simple adjustable-length rule \newcommand{\plongblank}[1]{\rule[-0.2ex]{#1}{0.15pt}}

For your particular application, instead of letting the rule go to the next line, leaving a blank space, you can split the rule into two parts.

e

\documentclass{article} 

\newcommand{\plongblank}[1]{\rule[-0.2ex]{#1}{0.15pt}}

% commenting this out makes the paragraph break evident
%\setlength{\parindent}{0pt}

\begin{document}            
    When passing parameters to a function by value, any changes that the function
    makes to the parameters \plongblank{3cm}
    reflected in the variables passed to the function in the calling function.
    
    \plongblank{5cm} describes the functionality in C++ where 2 or more functions share the same
    name, and the determination of which function is called is based on the number
    and/or type of parameters that are being passed.    
    
    This is a long line and the blank line   is  going to run off the page  \plongblank{2cm} \plongblank{3cm}.  
    
\end{document}
1

There are two issues:

(a) \hbox cannot start a paragraph. If you write \leavevmode\hbox you will force it to start a paragraph. The \hbox default width will be the natural width of the containing material. Wipet's answer has a good explanation as to the various modes, so I will not repeat it here.

(b) \dotfill produces leaders, but you are looking for "breakable leaders of a fixed size" (like the dots you see in a Table of Contents). You can think of it as "visible glue".

Here is a solution with LuaTeX. Uncomment the style of line you prefer. I used "text visible space" so you can see what is happening. The trick is to convince TeX to break the line by adding a very small space of "1sp". If you do not use LuaTeX, you can change the snippet with a TeX "\loop .. \repeat". As is trivial this is left as an exercise for the reader!

 \documentclass{article}
   \def\myleaders#1{
   \directlua{
   %local str = "\\_\\hskip1sp"    
    local str = "\\verb*+ +\\hskip1sp"
    local tstr = ""
    for i=1,#1 do
      tstr = tstr .. str
    end  
    tex.print("\\thinspace" .. tstr .. "\\thinspace")
   }}

   \begin{document}
   This is some text\myleaders{10} and this is some more \myleaders{30}

    When passing parameters to a function by value, any changes that the function
    makes to the parameters \myleaders{10}
    reflected in the variables passed to the function in the calling function.
    
    \myleaders{30} describes the functionality in C++ where 2 or more functions 
 share the same
    name, and the determination of which function is called is based on the number
    and/or type of parameters that are being passed.    
    
    This is a long line and the blank line   is  going to run off the page 
    \myleaders{30} 
    
    \myleaders{30}.  


    \end{document}

enter image description here

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.