2

I'm writing a class, and when using it I want to use small caps with a font that doesn't have small caps defined (I know – not as good as the real thing). I found this answer Fake small caps with XeTeX/fontspec? which I tried to include, however I get the errors:

Missing $ inserted. Missing $ inserted. You can't use '\spacefactor' in vertical mode.

However, the code works perfectly when it's pasted into the preamble.

Anyone know what's going on?

MWE

Class File

\ProvidesClass{custom}[a custom class]
\NeedsTeXFormat{LaTeX2e}

\DeclareOption*{
    \PassOptionsToClass{\CurrentOption}{scrreprt}
}
\ProcessOptions\relax

\LoadClass[usegeometry]{scrreprt}


\RequirePackage{graphicx}

\RequirePackage{plex-serif}

% Small Caps

\makeatletter
\newlength\fake@f
\newlength\fake@c
\def\fakesc#1{%
\begingroup%
\xdef\fake@name{\csname\curr@fontshape/\f@size\endcsname}%
\fontsize{\fontdimen8\fake@name}{\baselineskip}\selectfont%
\uppercase{#1}%
\endgroup%
}
\makeatother

\newcommand\fauxsc[1]{\fauxschelper#1 \relax\relax}
\def\fauxschelper#1 #2\relax{%
\fauxschelphelp#1\relax\relax%
\if\relax#2\relax\else\ \fauxschelper#2\relax\fi%
}
\def\Hscale{.83}\def\Vscale{.72}\def\Cscale{1.00}
\def\fauxschelphelp#1#2\relax{%
\ifnum`#1>``\ifnum`#1<`\{\scalebox{\Hscale}[\Vscale]{\uppercase{#1}}\else%
    \scalebox{\Cscale}[1]{#1}\fi\else\scalebox{\Cscale}[1]{#1}\fi%
\ifx\relax#2\relax\else\fauxschelphelp#2\relax\fi}

\makeatletter
\newcommand{\maketitleee}{
    \fauxsc{\@title}
}
\makeatother

Document

\documentclass[a4paper, 12pt, oneside]{custom}

\title{Title}
\author{Author}

\begin{document}

\maketitleee

\end{document}

Update

Removing all the \makeatletters and \makeatothers seems to change the errors given to those below

Errors

Update 2

This was fixed by @moewe's suggestion, which is replacing \fauxsc{\@title} with \expandafter\fauxsc\expandafter{\@title}

tecosaur
  • 1,033
  • 2
    Welcome to TeX.SX! Without seeing your code it is impossible to say what the problem is. Can you please add a minimal working example. A MWE should start with a \documentclass command, have a minimal preamble and then \begin{document}...\end{document}. The code should compile and be as small as possible to demonstrate your problem. Cutting your code down to a MWE may well reveal what your problem actually is. In any case, it is really difficult to help you without more information. –  Nov 13 '18 at 07:10
  • I'm not sure about the 'missing $ inserted' errors, but the 'You can't use '\spacefactor' in vertical mode.' comes up when you try to use or (re-)define a command name beginning with @ without using \makeatletter...\makeatother, see https://tex.stackexchange.com/q/8351/35864 (note how the answer in the linked question has \makeatletter...\makeatother around all commands with @ in their names). Class files and .sty files are automatically processed with \makeatletter on, which would explain why a command can be defined and used there, but not in the document. – moewe Nov 13 '18 at 07:10
  • @Andrew I've added some more info. Let me know if you'd like anything else. – tecosaur Nov 13 '18 at 07:15
  • I can't reproduce the errors you get, but if your code is the complete .cls file, there probably should be a \LoadClass{article} call at the beginning to load the basic LaTeX commands defined in the base classes – siracusa Nov 13 '18 at 07:38
  • 4
    please don't just post disconnected code fragments, post a single small example that we can run to get the error that you are asking about, otherwise it's very hard to guess the error and advise how to fix it. – David Carlisle Nov 13 '18 at 07:46
  • 1
    As David says, please post a full minimal working example: the code should be as small as possible so as to reproduce your error. You should either post a minimal latex document that exhibits the problem or, alternatively, a minimal class file together with a minimal latex document. The key thing is that we should be able to reproduce your error from the code that you post. It is virtually impossible to help you if you don't show us the problem. –  Nov 13 '18 at 08:02
  • Sorry about that. I think I've got the message now. You should find a complete MWE in the description now. – tecosaur Nov 13 '18 at 08:20
  • 1
    your definition of \maketitleee should have the \makeatletter/\makeatother outside, not inside. There might be other problems (code looks complicated). –  Nov 13 '18 at 08:28
  • Within the class file (.cls) you should not have to use \makeatletter and \makeatother at all - remove them. – moewe Nov 13 '18 at 08:31
  • @moewe No redefinition is done to \makeatletter and \makeatother. – egreg Nov 13 '18 at 08:33
  • @egreg I checked the sources shortly after I wrote that and saw that there are no redefinitions, so I removed that claim. – moewe Nov 13 '18 at 08:34
  • Without \makeatletter and \makeatother the macro doesn't work. Moving them outside did change the errors I was getting though, and now they won't go away even if I move that bit into the preamble. Seems like fakesc doesn't like being surrounded by \makeatletter and \makeatother. – tecosaur Nov 13 '18 at 08:39
  • If I remove the \makeatletter...\makeatothers (both pairs) and change to a different font (I don't have Plex installed), the MWE compiles fine without errors, the output also seems to be as expected. If you get an error or different problems when you remove the \makeat...s, please update your question accordingly. – moewe Nov 13 '18 at 08:45
  • @moewe It seems me simplifying things removed a cause of an error. I've updated the MWE. – tecosaur Nov 13 '18 at 08:49
  • 1
    There still is a \makeatletter and a \makeatother in your .cls file. Remove all \makeatletters and \makeatothers from the .cls. As I said before if I remove all of them (in the earlier version two pairs, now only one pair), the MWE compiles. – moewe Nov 13 '18 at 08:52
  • That's strange. I've had a different experience, here's my modified MWE https://pastebin.com/JQnU79xA which is giving me different errors. – tecosaur Nov 13 '18 at 09:28
  • 1
    Well that is an entirely different matter. In your earlier code you did not have \fauxsc around the \@title. The implementation of \fauxsc seems to impose conditions on its argument, try \expandafter\fauxsc\expandafter{\@title} instead. – moewe Nov 13 '18 at 09:51

1 Answers1

5

First and foremost: faking small caps for a font that hasn't them is hopeless.


When LaTeX is reading a .cls file, \makeatletter is implicitly in force and issuing \makeatother will most likely introduce problems.

Indeed it does, because when we arrive at defining \maketitlee, @ is an “other character”, so the definition becomes

• •\makeatletter•\@•t•i•t•l•e•\makeatother•

( is used to separate tokens). Note that when \maketitlee is called, the replacement text has already been tokenized, so \makeatletter will do nothing at all.

Never use \makeatletter and \makeatother in a .cls file except in the body of a macro definition that has among its actions inputting a file where the special treatment of @ is needed. This is not the case of your \maketitlee macro.


After removing \makeatletter and \makeatother everywhere in the class file, compiling your example .tex file produces no error and the output is

enter image description here

that clearly shows what I mean in the top line of this answer.

egreg
  • 1,121,712
  • I see, however — if I remove the \makeatletter and \makeatother it doesn't work. – tecosaur Nov 13 '18 at 08:45
  • @tecosaur I tried, of course. – egreg Nov 13 '18 at 08:48
  • Something that may throw a spanner in the works, after seeing this comment https://tex.stackexchange.com/questions/459738/defined-command-only-works-in-preamble/459749?noredirect=1#comment1156092_459738 I realised I needed to modify the MWE given, for me that MWE doesn't successfully compile. – tecosaur Nov 13 '18 at 09:30
  • However, this does solve the issue which I had (at least the first one). Thanks :) – tecosaur Nov 13 '18 at 10:03
  • 3
    In some situations better than \makeatletter..\makeatother is: \begingroup\makeatletter\@firstofone{\endgroup <Stuff where @ must be letter>} . This way the category code of @ will be reset to whatever it was before issuing the \makeatletter-command. \makeatother does set the category code of @ to 12 (other) no matter what it was before. – Ulrich Diez Nov 13 '18 at 11:13