9

In programming languages, you can define methods and functions which can get called from other methods or functions. This allows for modularity and readability in software. Is there an analogous construct in Latex?

For example, I want to use Latex to write my homework, which consists of say, questions 1,2,3.

Does Latex allow me to do something like:

main() {
    question1
    question2
    question3
}

question1() {
    # Latex code to produce my response to question 1
}

...

In addition to readability, one might want to do this so that they could easily comment out certain parts of the document so that they do not have to see such a large document at every compilation.

1
  • 1
    Yes, LaTeX does provide this. Typically it entails \newcommand and \newenvironment.
    – Werner
    Commented Nov 30, 2016 at 0:03

2 Answers 2

13

LaTeX has macros, which are different than functions in important ways but can serve the purpose you want. One important thing to note is that the document is evaluated top to bottom and definitions are made as Latex sees them, so you must define your macros before you call them. For instance:

\documentclass{article}
\newcommand\questionone{stuff}
\newcommand\questiontwo{second stuff}
\newcommand\questionthree{third stuff}
\begin{document}
\questionone
\questiontwo
\questionthree
\end{document}

The more common thing that people do that allows for modularity is to put the questions in separate files, say question1.tex, question2.tex, and question3.tex, then \input or \include the files. There is a command \includeonly which restricts which includes are actually done so the following will only input question2.tex:

\documentclass{article}
\includeonly{question2}
\begin{document}
\include{question1}
\include{question2}
\include{question3}
\end{document}    
2
  • Thanks for the tips. I would like to add for other Latex beginners such as myself that \include puts the contents on a new page, while \input puts the contents on the same page.
    – Phillip D.
    Commented Nov 30, 2016 at 0:16
  • 4
    Right, and there isn't a version of \includeonly for \input (you can make it, but it isn't a built in). Another important difference is that \include does not work recursively -- if you \include a file and that file tries to \include a file, LaTeX throws an error. On the other hand, included and inputted files can both use \input. Commented Nov 30, 2016 at 0:23
8

Please see EDIT below for what I'd actually recommend ...

I don't recommend doing it this way, but you could, if you wanted to define everything and then just say \main in your document itself.

\documentclass{article}
\newcommand*\main{%
  \begin{enumerate}
    \item\questionone
    \item\questiontwo
    \item\questionthree
  \end{enumerate}%
}
\newcommand*\questionone{%
  Here is my response to the first question:

  The best response ever!%
}
\newcommand*\questiontwo{%
  Here is my response to the second question:

  The second best response ever!%
}
\newcommand*\questionthree{%
  Here is my response to the third question:

  The third best response ever!%
}
\begin{document}
\main
\end{document}

three questions

As others have said, TeX uses macros. LaTeX 3 introduces the concept of functions and variables, but they are all still really just macros. LaTeX generally (the current version is 2e) has commands and environments but, again, they are all macros.

EDIT

I would actually recommend using a different approach. As suggested in Hood Chatham's answer, I'd put the responses into separate files: question1.tex, question2.tex, question3.tex, questionABX.tex and so on. Then I would define a macro to take a list of questions to be included

\main{<comma-separated list of questions>}

For example,

\main{3,ABX}

or

\main{2,1,3}

or whatever.

Here's an example using LaTeX 3's syntax:

\begin{filecontents}{question1.tex}
  Here is my response to the first question:

  The best response ever!
\end{filecontents}
\begin{filecontents}{question2.tex}
  Here is my response to the second question:

  The next best response ever!
\end{filecontents}
\begin{filecontents}{question3.tex}
  Here is my response to the third question:

  The last best response ever!
\end{filecontents}
\begin{filecontents}{questionABX.tex}
  Here is my response to another question:

  This is another great response!
\end{filecontents}

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \l_phillip_qlist_clist
\msg_new:nnn { phillip ~ questions } { question file not found } {
   phillip ~ questions  ~::~question~#1~requested~but~question#1.tex~not~found.~\msg_line_context:.
}
\NewDocumentCommand \main { m }
{
  \phillip_print_responses:n { #1 }
}
\cs_new_protected_nopar:Nn \phillip_print_responses:n
{
  \clist_set:Nn \l_phillip_qlist_clist { #1 }
  \clist_map_inline:Nn \l_phillip_qlist_clist
  {
    \file_if_exist:nTF { question##1 }
    {
      \file_input:n { question##1 }
      \par
    }
    {
      \msg_fatal:nnn { phillip ~ questions } { question file not found } { ##1 }
    }
  }
}
\ExplSyntaxOff
\begin{document}
\main{1,2,,3}
\hrule
\main{1,2}
\hrule
\main{3,1}
\hrule
\main{2,ABX}
\end{document}

selecting questions

8
  • I didn't think to make a main macro too, this actually preserves the order he gave in his question. Commented Nov 30, 2016 at 0:25
  • @HoodChatham I think your approach is the more natural one. I just thought it might be worth illustrating the fact that you could do it this way, if you wanted to. I guess there may be some limit to this method, actually, but I'm not sure. (Could a 1,000 page book be reduced to just \main?! It would sure make debugging the code fun ....
    – cfr
    Commented Nov 30, 2016 at 0:27
  • I think the biggest disadvantage of this approach is that that no environments that make catcode changes would function correctly. I would hope that with a modern tex installation it should be fine to make a humongous macro, but I guess there could be issues. Commented Nov 30, 2016 at 0:30
  • Of course the catcode problem is already a disadvantage of putting code into question macros. Commented Nov 30, 2016 at 0:33
  • @HoodChatham Indeed. In fact, I wouldn't use either your method or mine, but I would prefer yours to mine.
    – cfr
    Commented Nov 30, 2016 at 0:34

You must log in to answer this question.

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