\newcommand and \renewcommand difficulty in class file

2,009

Solution 1

For this implementation I'd suggest using \assigntitle not just to update some internal macro, but also to set the actual title:

\newcommand{\assigntitle}[1]{%
  \begin{center}
    \huge \upshape Assignment \# #1 \\
    \normalsize \normalfont \@date
  \end{center}
}

If you want to set a date other than \today, the you'd use

\date{January 1, 2001}
\assigntitle{4}

Solution 2

The basic problem is that \@assignment is used right at the start of the document body within \AtBeginDocument, so using \assigntitle{4} etc. after \begin{document} is ineffective, since the redefined \@assignment is never used then.

\centering should not occur outside of a group, so use \begingroup...\endgroup.

I suggest to use a pagestyle header (e.g. fancyhdr) rather which is updated, also using counters.

Assignment.cls

\ProvidesClass{Assignment}
\NeedsTeXFormat{LaTeX2e}

\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions

\LoadClass[11pt,letterpaper]{article}

\newcommand{\@assignment}{Assignment \#}
\newcommand{\assigntitle}[1]{\edef\@assignment{Assignment \#{#1}}}


\AtBeginDocument{%
  \begingroup
  \centering 
  \huge \upshape \@assignment 
  \medskip

  \normalsize \normalfont \@date

  \bigskip

  \endgroup
}

\endinput

driver.tex

\documentclass{Assignment}


\assigntitle{4}

\begin{document}
\end{document}

Solution 3

It's a “chicken and egg” problem: with this code you must state \assigntitle{4} before \begin{document}.

An alternative and perhaps better strategy is to it with \maketitle:

\ProvidesClass{Assignment}
\NeedsTeXFormat{LaTeX2e}

\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions

\LoadClass[11pt,letterpaper]{article}

\newcommand{\@assignment}{Assignment \#}
\newcommand{\assigntitle}[1]{\renewcommand{\@assignment}{Assignment \#{#1}}}

\renewcommand\maketitle{%
    \begingroup % <----- don't forget this one
    \centering \huge \upshape \@assignment \\
    \normalsize \normalfont \@date
    \bigskip
    \endgroup % <----- matching \begingroup
}

\endinput

Now your sample document can be in any of the two forms below

\documentclass{Assignment}

\assigntitle{4}

\begin{document}

\maketitle

\end{document}

or

\documentclass{Assignment}

\begin{document}

\assigntitle{4}

\maketitle

\end{document}

You can add \date{July 28, 2016} anywhere before \maketitle.

The \begingroup and \endgroup tokens I added are necessary if you don't want \centering going on for the whole document.

If you still need \maketitle, use a different name for the command producing the header.

Note that typesetting material using \AtBeginDocument is not recommended, because several packages that a user might add after declaring the class do their business using that hook and so they would act after the header has been typeset.

Share:
2,009

Related videos on Youtube

Michelle
Author by

Michelle

Updated on August 01, 2022

Comments

  • Michelle
    Michelle over 1 year

    I am making an "Assignment" class file. One element of my class is not working correctly. I want to be able to input the assignment # in the latex file, using \assigntitle{4} and have a centered Assignment #4 printed at the top of the page. I use a \newcommand and \renewcommand to implement this in the class file. Alas this portion is not working. I only get the predefined output from the \newcommand definition and not my value input from the latex file. I think it is because of a scoping issue, but I can't figure out how to get around it. I tried to use \global\def\ but this didn't work. I think \renewcommand can't use this type of \def. If I am wrong, please inform me.

    I have removed extraneous code (and yes I have tried it with only this code) from the full file, of which I show below.

    \ProvidesClass{Assignment}
    \NeedsTeXFormat{LaTeX2e}
    
    \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
    \ProcessOptions
    
    \LoadClass[11pt,letterpaper]{article}
    
    \newcommand{\@assignment}{Assignment \#}
    \newcommand{\assigntitle}[1]{\renewcommand{\@assignment}{Assignment \#{#1}}}
    
    
    \AtBeginDocument{%
        \centering \huge \upshape \@assignment \\
        \normalsize \normalfont \@date
        \bigskip
    }
    
    \endinput
    

    example.tex

    \documentclass[english]{Assignment}
    
    \begin{document}
    
    \assigntitle{4}
    
    \end{document}
    
    • Admin
      Admin over 7 years
      Welcome to TeX.SX! It would really help if you would post a sample file that uses this class.
    • Werner
      Werner over 7 years
      Where do you make a call to \assigntitle in your main .tex document?
    • Michelle
      Michelle over 7 years
      @Werner I have edited the question to show the usage. In order for the class to be used with Lyx, I think it has to be called after begin{document} ...at least that is where Lyx puts it.
    • Werner
      Werner over 7 years
      @Michelle: Using LyX makes it clear now. I've suggested an alternative definition of \assigntitle below, which might suit your needs.
  • Michelle
    Michelle over 7 years
    Great idea redefining \maketitle. The block surrounding\centering was removed (had other code in it) in an attempt for clarity, which now has it completely opened, so yes I will have that covered, but thanks for reminding me.
  • Michelle
    Michelle over 7 years
    OK, this is very helpful. I now see why it wouldn't work. I can manually get it to work now. Because I want to pair this with Lyx, I want to let \assigntitle{4} be call after begin{document}.
  • Michelle
    Michelle over 7 years
    You mean I made it more complicated than it need be? :) This works nice. I guess I was trying to have a default, but now that I think about it that could be dangerous (putting the wrong number on an assignment).
  • Werner
    Werner over 7 years
    @Michelle: Since you most likely want to set the title when you set the assignment number, joining the definition seems appropriate.
  • Admin
    Admin over 7 years
    @Michelle: You made your decision already, (and unaccepted an already accepted solution, after editing your question), so no chance to improve my answer...