4

Question: Is there an environment similar to the comment environment that suppresses text and space but can be called using inline commands?

I'm trying to develop a better way to type my solutions into my homework sets. Ideally, I'd like to have something in the preamble that I comment/uncomment to include/exclude solutions. I have a MWE below to demonstrate the type of thing I'm trying to implement, but of course, in it's current form, it doesn't work.

\documentclass[12pt]{article}

\newenvironment{solution}{}{}

\newcommand{\soln}{\begin{solution}}
\newcommand{\solnend}{\end{solution}}

\newcommand{\nosolutions}{
    \renewcommand{\soln}{\begin{comment}}
    \renewcommand{\solnend}{\end{comment}}
}

%\nosolutions

\begin{document}
    What is a question?

    \soln
        Not an answer.
    \solnend
\end{document}

I know of one way to partially succeed in what I'm trying to do, and that is to define the new command with an optional argument. The issue I have with this is that when I have a problem with multiple parts that is quite long, it may take a non-trivial amount of time to actually locate the relevant part of the code (for reference, I'm using WinEdt paired with Sumatra, so I can double click the pdf in Sumatra and it takes me to that part of the code; with an optional argument, though, I'm always taken to the very end). A MWE demonstrating this method is below.

\documentclass[12pt]{article}

\newenvironment{solution}{}{}

\newcommand{\soln}[1]{\begin{solution}#1\end{solution}}

\newcommand{\nosolutions}{
    \renewcommand{\soln}[1]{}
}

\nosolutions

\begin{document}
    What is a question?

    \soln{
        Not an answer.
    }
\end{document}

The ending question: is there anything like the comment environment available that suppresses text and space?

10
  • Can you say what exactly is wrong with using \includecomment{solution} (or \excludecomment{solution}) and just using \begin{solution} and \end{solution} everywhere? (Why is it that you insist on "inline commands" instead of "environments"?) Nov 22, 2019 at 18:22
  • @WillieWong: I'm not sure I understand the question exactly. I did try using \excludecomment{solution} in one of my attempts, but I couldn't get the file to compile. To answer the second question: there is no particular reason, it was just simply my goal.
    – Clayton
    Nov 22, 2019 at 18:27
  • did you load the comment package? Nov 22, 2019 at 18:27
  • @WillieWong: Indeed. :)
    – Clayton
    Nov 22, 2019 at 18:29
  • 1
    Possible duplicate: Commenting out large sections
    – Werner
    Nov 22, 2019 at 19:03

3 Answers 3

9

I think the package scontents is adapted to this job, if I understood your question and the example file:

\documentclass{article}
\usepackage{scontents}
\newenvsc{solution}[store-env=solution,print-env=false]
\pagestyle{empty}
\setlength{\parindent}{0pt}
\begin{document}
\section{Only questions}
What is a question?

\begin{solution}
  Not an answer.
\end{solution}

What is the next question?

\begin{solution}
  An answer.
\end{solution}

\section{Questions with answer}
Other question?

\begin{solution}[print-env=true]
  Other answer.
\end{solution}

\section{Only solutions}
% Print solutions
\getstored[1]{solution}\par
\getstored[2]{solution}

% OK, print last
\getstored[3]{solution}

\section{Use default command}
Really another question?
\Scontents[store-cmd=solution]{Yes, other answer}

% now print
\getstored[4]{solution}
\end{document}

print-en=false

If we switch to print-env=true

print=env=true

The truth is you can play with the package options, using the command \setupsc or with the local options [print-env=<true|false>] and [print-cmd=<true|false>], the current version does not (yet) allow you to create a custom command, only environments, I recommend you read the documentation. (Credit to @Werner for example)

2
  • 1
    Thanks! I think this is exactly what I was asking about. For future readers: Willie Wong's comment on the original post (regarding the exam class) provided me the tools to accomplish what I was going for along with the tools to do many other things. However, as far as answers go, I think this answer most cleanly solves the problem.
    – Clayton
    Nov 23, 2019 at 2:10
  • @Clayton: This package was born, among many other ideas, a little to give answer to this type of problematic (the classic files of question/answer). The exam class is very good, although today I prefer to use xsim package, I'm glad my answer is helpful, good luck with your work. Nov 23, 2019 at 2:26
5

You can define \soln to grab everything up to \solnend and then either set it (\showsolutions) or not (\nosolutions).

\documentclass{article}

\newcommand{\showsolutions}{\long\def\soln##1\solnend{##1}}
\newcommand{\nosolutions}{\long\def\soln##1\solnend{}}

\showsolutions
%\nosolutions

\begin{document}

What is a question?

\soln
  Not an answer.
\solnend

What is the next question?

\soln
  An answer.
\solnend

\end{document}

With \showsolutions:

enter image description here

With \nosolutions:

enter image description here


To understand the definition of \soln, you'll have to understand how \def works. \def has the following syntax (from p 203 of The TeX Book):

Definitions have the general form

\def<control sequence><parameter text>{<replacement text>}

where the <parameter text> contains no braces, and where all occurrences of { and } in the <replacement text> are properly nested. Furthermore the # symbol has a special significance: In the <parameter text>, the first appearance of # must be followed by 1, the next by 2, and so on; up to nine #'s are allowed. In the <replacement text> each # must be followed by a digit that appeared after # in the <parameter text>, or else the # should be followed by another #. The latter case stands for a single # token when the macro is expanded; the former case stands for insertion of the corresponding argument.

...

How does TeX determine where an argument stops, you ask. Answer: There are two cases. A delimited parameter is followed in the <parameter text> by one or more non-parameter tokens, before reaching the end of the parameter text or the next parameter token; in this case the corresponding argument is the shortest (possibly empty) sequence of tokens with properly nested {...} groups that is followed in the input by this particular list of non-parameter tokens. (Category codes and character codes must both match, and control sequence names must be the same.) An undelimited parameter is followed immediately in the <parameter text> by a parameter token, or it occurs at the very end of the parameter text; in this case the corresponding argument is the next non-blank token, unless that token is '{', when the argument will be the entire {...} group that follows. In both cases, if the argument found in this way has the form '{<nested tokens>}', where <nested tokens> stands for any sequence of tokens that is properly nested with respect to braces, the outermost braces enclosing the argument are removed and the <nested tokens> will remain.

The definition of \soln (under \showsolutions) uses a delimited parameter in the <parameter text>:

\def\soln#1\solnend{#1}

As such, \soln will grab everything following \soln up to an explicit \solnend in the input stream (so, effectively, everything between \soln and \solnend, and call that #1) and set it as-is (the <replacement text> is just whatever is grabbed - #1). So, you can't use \soln without a future \solnend in the input stream; they to together.

Under \nosolutions, the same happens (a delimited parameter in the <parameter text>), but whatever captured is never set (no #1 within the <replacement text>).

We use a \long \definition, because the argument #1 - whatever is between \soln and \solnend - could contain paragraphs of text (otherwise a regular \def would suffice).

Also, since the definition of \soln is made within another macro (\showsolutions and/or \nosolutions), doubling of the # is necessary (see the answer to Exercise 20.5 on p 329 within the TeX Book).

2
  • As a nonexpert in LaTeX, can you explain how this implementation actually works? I see what you've typed and I can usually figure out what each thing is doing, but this answer seems to have details that I'm wholly unfamiliar with.
    – Clayton
    Nov 22, 2019 at 23:14
  • @Clayton: I've added some detail about the \definition of \soln at the end of the answer.
    – Werner
    Nov 22, 2019 at 23:51
4

The following basic example should work

\documentclass{article}

\usepackage{comment}

\includecomment{soln} % Change to \excludecomment if you don't want solutions printed

\begin{document}
Q: why does the chicken cross the road.

\begin{soln}
A: To get to the other side
\end{soln}
\end{document}

If instead of environments and you want to, absolutely, use macros to turn on and off commenting, there's some historical code that you can look at that does the sort of thing you want.

3
  • Does this treat soln as an environment? That is, if I want to change the formatting of soln, is there a way to do that? Something to clearly distinguish it from the text of the problem?
    – Clayton
    Nov 22, 2019 at 19:04
  • If you want to format soln, please read Section 3 of the documentation for the comment package. Nov 22, 2019 at 19:10
  • My apologies, Willie; I've been busy. I'm reading through the documentation for the exam class and think that this will probably be something I want to utilize. I appreciate you bringing it to my attention; if I can get it to work in exactly the way I want, I'll certainly accept this answer. In the interim, I leave an upvote and my a note of my gratitude. :)
    – Clayton
    Nov 22, 2019 at 23:13

You must log in to answer this question.

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