3

I was customizing a beamer theme that have to be used by many people at my workplace. I want to show an error whenever frame-title takes more than two lines. Please don't ask why title is so long. So I thought that by defining a custom length and setting it to the width of frame-title, I can compare this custom length to a threshold value and show the error. However I am not able to set the width of my custom length to frame-title. The error I am getting is undefined control sequence. An MWE is as following:

\documentclass{beamer}

\makeatletter
    \newlength \myl
    \def \cm {\beamer@frametitle}
    \settowidth{\myl}{\cm}  %error ! Undefined control sequence.
    %\settowidth{\myl}{Example frame} %68.2551pt
\makeatother

\begin{document}
    \begin{frame}{Example frame}
        \the \myl  
    \end{frame}
\end{document}

I am new to custom themes. So If anyone can help me for if construct of lengths with a greater than comparison. It will be grate for me. I already tried using \if and \ifx available on wikibooks which both did not work.

5

The following example patches the \frametitle command to update the length \titlelen that gives the length of the title under the current theme's font:

enter image description here

\documentclass{beamer}

\let\Tiny\tiny% http://tex.stackexchange.com/a/94159/5764

\usepackage{etoolbox}

\makeatletter
\newlength{\titlelen}
\tracingpatches
\patchcmd{\beamer@@frametitle}% <cmd>
  {\gdef\beamer@frametitle}% <search>
  {\settowidth{\titlelen}{\usebeamerfont{frametitle}#2}%
   % ...condition here, if necessary...
   \gdef\beamer@frametitle}% <replace>
  {}{}% <success><failure>
\makeatother

\begin{document}

\begin{frame}{Example frame}

  {\usebeamerfont{frametitle}Example frame}

  \rule{\titlelen}{1pt}

  \the\titlelen

\end{frame}

\end{document}

While some action can be taken at the step indicated above, the changed macro - \beamer@@frametitle - constructs the frame title setting not just via \beamer@frametitle, but also \insertframetitle. So, if you wish to change the frame title to (say) "Too long" if the users inputs (say) "This is a super long frame title that is actually too long", then the following setup might work better:

enter image description here

\documentclass{beamer}

\let\Tiny\tiny% http://tex.stackexchange.com/a/94159/5764

\makeatletter
\newlength{\titlelen}
\long\def\beamer@@frametitle[#1]#2{%
  \settowidth{\titlelen}{\usebeamerfont{frametitle}#2}%
  \beamer@ifempty{#2}{}{%
    \ifdim\the\titlelen>300pt\relax
      \gdef\beamer@frametitle{Too long}%
    \else
      \gdef\beamer@frametitle{#2}%
    \fi
    \gdef\insertframetitle{{\beamer@frametitle\ifnum\beamer@autobreakcount>0\relax{}\space\usebeamertemplate*{frametitle continuation}\fi}}%
    \gdef\beamer@shortframetitle{#1}%
  }%
}
\makeatother

\begin{document}

\begin{frame}{This is a super long frame title that is actually too long}

  {\usebeamerfont{frametitle}Example frame}

  \rule{\titlelen}{1pt}

  \the\titlelen

\end{frame}

\end{document}
  • Thanks @Werner for your answer. It is the thing I was looking for. I used '\ifdim \titlelen>300pt \gdef\beamer@frametitle} {Too long}{}' but it is giving error. Can you redirect me to correct construct. – Birendra Singh May 3 '16 at 8:48
  • @VirendraSingh: See the updated answer... – Werner May 3 '16 at 20:15
5

First, why not just use \insertframetitle? Second, I don't think \beamer@frametitle is defined outside of a frame. That's why you probably get the error message. Third, you should also consider the font (shape, size, ...) in your calculations. Have a look at this example.

\documentclass{beamer}

\newlength\myframetitlelength

\begin{document}
    \begin{frame}{Example frame}
        \insertframetitle
        \settowidth{\myframetitlelength}{\insertframetitle}
        \the\myframetitlelength

        Example frame%
        \settowidth{\myframetitlelength}{Example frame}
        \the\myframetitlelength

        {\usebeamerfont{frametitle}\insertframetitle}
        \settowidth{\myframetitlelength}{\usebeamerfont{frametitle}\insertframetitle}
        \the\myframetitlelength
    \end{frame}
\end{document}

OUTPUT: beamer_frametitle


This example demonstrates why using \insertframetitle makes sense here. The threshold (100pt) is set just between the two widths of the first and second frame. You should obviously change it to a higher value.

\documentclass{beamer}
\usepackage{lipsum}

\newlength\myframetitlelength

\addtobeamertemplate{frametitle}{%
  \settowidth{\myframetitlelength}{\usebeamerfont{frametitle}\insertframetitle}%
  \ifdim\myframetitlelength>100pt%
    \PackageWarning{}{Frametitle is too long: \the\myframetitlelength.}%
  \fi%
}

\begin{document}
    \begin{frame}[allowframebreaks]{Example frame}
        \lipsum[1-2]
    \end{frame}
\end{document}
  • For your question I will say that in the definition of \insertframetitle there is some complicated code whereas I found \beamer@frametitle more clear. Being new to these things I prefer clearer code. Well thanks for your answer. – Birendra Singh May 3 '16 at 8:35
  • 1
    The "complicated code" you are talking about is to support frame breaks (allowframebreaks option). So thinking about it again, \beamer@frametitle and also Werners solution will result in a wrong width in these cases. So you really should use \insertframetitle. – Benjamin May 3 '16 at 8:52
  • Actually the font settings are internal and same for everyone. – Birendra Singh May 3 '16 at 8:56
  • I added an example to my answer to demonstrate why you should use \insertframetitle. – Benjamin May 3 '16 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.