7

Discl.: I have been using LaTeX for many years, but I am a beginner on the more advanced macro stuff.

For a specific hack of a latex document of mine, I want to override the use of \hrule within a command provided by a package I am using. Specifically I want to redefine \hrule to do nothing, perform the command of the package, and then restore \hrule to its previous definition.

Hence I want to do something along the lines of this:

\let\hruleold\hrule
\def\hrule(#1)(#2)(#3){}
\packagespecficcommand
\let\hrule\hruleold 

Which gives me the error:

! Use of \hrule doesn't match its definition.

What is the correct approach to achieve this?

-- Edit 1 (more specific error) --

I tried the following, as suggested by Herbert:

\let\hruleold\hrule
\def\hrule(#1)(#2)(#3){#1,#2,#3}
\maketitle
\let\hrule\hruleold

which gives me this error

! Use of \hrule doesn't match its definition.
\@packagespecficcommand...skip -\topskip \fi \hrule \@height 
                                                   0.35mm\noindent \advance \...
6
  • Welcome to TeX.sx! A tip: You can use backticks ` to mark your inline code as I did in my edit.
    – hpesoj626
    Commented Mar 14, 2013 at 13:27
  • I don’t know a \hrule macro that accepts three parameters delimited in ( and ). Do you maybe mean the LaTeX \rule macro? Commented Mar 14, 2013 at 13:28
  • \let\hrule\relax, maybe?
    – Keks Dose
    Commented Mar 14, 2013 at 13:32
  • 1
    @KeksDose Won't work because \hrule is used as \hrule height 2pt etc., and if \hrule itself is a no-op, the arguments will remain.
    – Ryan Reich
    Commented Mar 14, 2013 at 13:35
  • 1
    The only way I see is redefining the macros in the package that use \hrule. As David Carlisle explains, \hrule is a primitive command with a very peculiar syntax and is used in many LaTeX constructs, which will most likely break if \hrule is redefined.
    – egreg
    Commented Mar 14, 2013 at 14:35

2 Answers 2

5

As suggested in the comments all sort of errors are bound to happen here. hrule even when let to \relax, will still leave its argument in the stream. For example the \textunderscore macro only takes a width argument (the height defaults to the TeX default) and elsewhere it might even have other arguments such as \hfill in the definition of \hrulefill. See the example below.

\documentclass{article}
\makeatletter
\def\hrulefill{\leavevmode\leaders\hrule\hfill\kern\z@}
\DeclareTextCommandDefault{\textunderscore}{%
 \leavevmode \kern.06em\vbox{\hrule\@width.3em}}

\begin{document}

\let\hrule\relax

a\textunderscore b

\end{document}

It will be preferable to rather set it's arguments to 0pt i.e., \@width etc if you know them and perhaps do all these within a group.

14

You really don't want to do this.

Firstly as has been noted in comments \hrule does not take {} or () delimited arguments, secondly if you do redefine \hrule you not only change the behaviour of an explicit \hrule in the document (which by the way isn't correct LaTeX syntax anyway) but you also change (and most likely break) the behaviour of every latex command that uses \hrule internally. These include at least \vspace \hrulefill \textunderscore \textvisiblespace \frame \framebox \fbox \hline \cline \oval \footnoterule

If I included all the commands and environments that depended on \vspace the list would be a lot longer.

You must log in to answer this question.

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