The standard is the DTX format where you put the documentation as comments around your code. Normally in the comment all code is wrapped in macrocode
environments and macros again in macro
environment. It is then compiled using the ltxdoc
class which uses the doc
package.
See more information about DTX at the TeX FAQ: https://texfaq.org/FAQ-dtx
Example:
% \begin{macro}{\mymacro}
% Some explanation
% \begin{macrocode}
\def\mymacro#1#2{%
\relax
\dosomething
% \end{macrocode}
% Explain the next part of the macro
% \begin{macrocode}
\domore
\expandafter\some\code
}
% \end{macrocode}
% \end{macro
Note that you can autogenerate a DTX file from any package or other code file using the sty2dtx
script.
Update.
Added support to leave the empty environment in the copy, removing only its contents, or to remove also the \begin...\end
pair (by default).
I programmed a LuaLaTeX solution and tried to make it flexible enough. These are the files which compose the solution:
remove-env.lua
-- remove-env.lua
omittedEnvironments = {}
omitFileSuffix = "-without"
leaveEmptyEnvs = false
function shouldOmit(line)
for i,v in ipairs(omittedEnvironments) do
if (string.find(line, "\\begin{"..v.."}")~=nil) then
return true
end
end
return false
end
function shouldResume(line)
for i,v in ipairs(omittedEnvironments) do
if (string.find(line, "\\end{"..v.."}")~=nil) then
return true
end
end
return false
end
function dumpfile()
myout = io.open(tex.jobname..omitFileSuffix..".tex", "w")
myin = io.open(tex.jobname..".tex", "r")
omitting = false
for line in myin:lines() do
if (not omitting and shouldOmit(line)) then
if (leaveEmptyEnvs) then myout:write(line.."\n") end
omitting = true
end
if (not omitting) then
myout:write(line.."\n")
end
if (omitting and shouldResume(line)) then
if (leaveEmptyEnvs) then myout:write(line.."\n") end
omitting = false
end
end
myout:close()
myin:close()
end
remove-env.tex
\directlua{dofile("remove-env.lua")}
\def\omitEnvironment#1{\directlua{table.insert(omittedEnvironments, "#1")}}
\def\omitFileSuffix#1{\directlua{omitFileSuffix="#1"}}
\def\leaveEmptyEnvs{\directlua{leaveEmptyEnvs=true}}
\def\removeEmptyEnvs{\directlua{leaveEmptyEnvs=false}}
\AtEndDocument{\directlua{dumpfile()}}
MWE.tex
\input remove-env
\documentclass{article}
\usepackage{fontspec}
\usepackage{lipsum}
\newenvironment{solution}{}{}
\omitEnvironment{solution}
\omitFileSuffix{-sans-sol}
\begin{document}\parindent0pt\parskip1em
1. \lipsum[1]\hrulefill\par
\begin{solution}
2. \lipsum[2]\hrulefill\par
\end{solution}
3. \lipsum[3]\hrulefill\par
\end{document}
This MWE defines a no-op solution
environment which acts simply as markup, but of course you can define it in a way that produces some effect in the pdf. Macro \omitEnvironment
specifies the environment you want to omit. You can use this macro several times to specify several environments, and all of them will be omitted. Macro \omitFileSuffix
specifies the suffix that will be appended to the output filename.
Run:
$ lualatex MWE.tex
And you will get two files (and all the usual auxiliar files, of course):
MWE.pdf
will be generated as usually, and all the contents (including omitted environments) will be present.
MWE-sans-sol.tex
is a copy of MWE.tex
in which all solution
environments are removed.
$ diff MWE.tex MWE-sans-sol.tex
11,13d10
< \begin{solution}
< 2. \lipsum[2]\hrulefill\par
< \end{solution}
If you want to remove only the contents of the solution but leave the empty environment, you only have to specify \leaveEmptyEnvs
at some point of MWE.tex
. In this case the diff will show:
$ diff MWE.tex MWE-sans-sol.tex
12d11
< 2. \lipsum[2]\hrulefill\par
PS: Thanks to Scott H. who suggested me not to use luatex callbacks, which was my first (and too convoluted) approach
Best Answer
The following is an attempt at creating a glossary of (La)TeX-related terms. The definitions are intentionally very short. If there are related question that ask about the term are tags corresponding to the term, links are provided.
This is a CW answer, so please add additional terms and/or definition and fix any errors you might find.
biblatex
. See bibtex vs. biber and biblatex vs. natbib and bibernatbib
orbiblatex
. See bibtex vs. biber and biblatex vs. natbib and bibtex\,
.\i
or\input
.\def
or\let
; in →LaTeX the recommended mechanism is to use\newcommand
or\renewcommand
.\documentclass{⟨name⟩}
, typically at the first line of the document. Examples areletter
,article
,book
,memoir
and the →KOMA-Script classes. Cf. document-classes and documentclass-writing\
. They are processed by TeX by first →expanding them and then processing the remaining →primitives. A synonym of →control sequence. Cf. macros\usepackage{⟨package-name⟩}
in the →preamble. Cf. packages and package-writing.\begin{document}
where the user sets the specification of the document as a whole and the →packages to be loaded for the →commands to come later in the body. Cf. preamble\expandafter
are of this type). They are somewhat similar to the keywords in a programming language.\protect
or when defining the command with\DeclareRobustCommand
.texdoc ⟨package⟩
will show the documentation for⟨package⟩
. It is also available online at www.texdoc.net. Cf. texdocSee also File extensions related to LaTeX, etc