Q:

Written response spaces for a workbook in ConTeXt

I am making a workbook in ConTeXt. Throughout the workbook, there will be many spaces for the owner to write in short answers of one or two paragraphs. This can be quite simple, perhaps just a question, followed by several thin, horizontal lines on which one can write. E.g.:
1. What was the most interesting part of the story?
__________________________________________________
__________________________________________________
__________________________________________________
__________________________________________________
__________________________________________________
__________________________________________________

Does TeX or ConTeXt have any standard method for providing such a space?
Are there any algorithms in place within TeX or ConTeXt for specifying proper typographical placement of these elements and where breaks should appear? Here is an example of what I mean (although not necessarily ideal):

No page break should be placed inside the writing area, unless the area before and after the break has at least 3 lines.
No page break should be placed between the question and the writing area.
Rather than specifying an exact number of lines, a range can be specified (e.g. 5 to 8 lines). E.g. If it prints 5 lines, but finds the rest of the page is empty, it can add up to 3 additional lines until the page is filled).

A:

Here's an attempt. Some code can be added to avoid breaks before three lines have been printed or less than three lines are to be typeset. If you don't want that the rest of last question line has a rule, then delay the setting of \parfillskip=0pt to just before the loop and turn the first four lines of \stopplainlines into \par.
\def\startplainlines#1{%
  \par\begingroup
  \parindent=0pt
  \parfillskip=0pt
  \def\numberoflines{#1}%
}
\def\stopplainlines{%
  \unskip % emulate \par's behavior
  \hskip.5em plus .2em minus .1em\nobreak\penalty-50 % insert a good break point
  \hbox{}\nobreak %
  \hrulefill\hbox{}\par % fill the remaining space with a rule
  \nobreak % don't break a page here
  \baselineskip=1.2\baselineskip
  \count255=\numberoflines\relax
  \loop\ifnum\count255>0 % produce the requested number of lines
    \leavevmode\hrulefill\hbox{}\endgraf
    \advance\count255 by -1
  \repeat
  \endgroup
}

\startplainlines{4}
Give a short proof of Fermat's last theorem
\stopplainlines

\bye

A:

In addition to egregs solution I want to present another solution that has a more ConTeXtish interface and supports minimal and maximal values.
Warning: I didn't test this code extensively, it might break unexpectedly.
\def\startmyrules{%
    \dosingleempty\dostartmyrules}

\def\dostartmyrules[#1]#2\stopmyrules{%
    \bgroup
    \define\linesleft{\numexpr(\pagegoal-\pagetotal)/\lineheight\relax}
    \getparameters[MR][#1]
    \setbox\scratchbox\vbox{#2}
    \nobreak % avoid page break after head
    \determinenoflines{\scratchbox}
    % more space available then max lines + head
    \ifnum\linesleft>\numexpr\MRmax+\noflines\relax
        #2\crlf
        \thinrules[n=\MRmax]
    \else
        % min lines + head doesn't fit on this page
        \ifnum\linesleft<\numexpr\MRmin+\noflines+1\relax
            \page
            #2\crlf
            \thinrules[n=\MRmax]
        % remaining space is between min and max + head
        \else
            \scratchcounter\MRmax
            \loop\ifnum\scratchcounter>\numexpr\MRmin-1\relax
                \ifnum\linesleft>\numexpr\scratchcounter+\noflines\relax
                    #2\crlf
                    \thinrules[n=\scratchcounter]
                \fi
                \advance\scratchcounter by -1
            \repeat
        \fi
    \fi
    \egroup
}

Demonstration that it works in some simple cases:
\starttext

\dorecurse{35}{\recurselevel\crlf}

\startmyrules [min=2, max=8]
1. What was the most interesting part of the story?
\stopmyrules
\page

\dorecurse{36}{\recurselevel\crlf}

\startmyrules [min=2, max=8]
1. What was the most interesting part of the story?
\stopmyrules
\page

\dorecurse{37}{\recurselevel\crlf}

\startmyrules [min=2, max=8]
1. What was the most interesting part of the story?
\stopmyrules

\stoptext

The output is:
 
 
The algorithm is as follows: If there is enough space for the head (the line what was the most… in this case) and the maximal number of lines provided as an argument, then they get printed. On the other hand if there is not enough space for the minimal amount of lines incl. head, everything is moved to another page. If it is inbetween, then a loop is invoked to determine the optimal number of lines.

