5

I want to automate the generation of my Contents slide in beamer, that I customized using TikZ. I currently do it manually.

Context

I aim to create my own beamer style. That is why I have defined a layout for my frame(s) Contentssee below, left:

enter image description here

The frame is structured as following — see above, right :

  • I define an oblique line (A) -- (B)see red dots
  • On this line, I defined two points : (top) and (down)see blue dots
  • Section numbers and titles are then evenly spread on this line, between the (top) and (down) boundaries — see yellow dots, and below for cases with one and two sections
    enter image description here

Question

However, this whole structure is manually defined. How could I automate the generation of such frames?

I see two subproblems:

  • Generate points (one), (two), etc.
    Computing their positioning is fairly easy, since they are defined as \node [yellow] (Number) at ($(top)!X!(down)$) {}; where : x = <section number> / (<total number of sections> +1)

  • Generating the label's nodes with \thesection and \secname (the latter found thanks to this question) for each section.


MWE

\documentclass{beamer}
    \usepackage[T1]{fontenc}
    \usepackage[utf8]{inputenc}
    \usepackage{tikz}
        \usetikzlibrary{calc}
        \usetikzlibrary{positioning}

\begin{document}
    \begin{frame}{Basic structure}
        \begin{tikzpicture}
        [
            overlay, 
            remember picture, 
            inner sep=0pt,  
        ]
        %% Defining points A and B
            \node [red] (A) at ($(current page.north west)+(3, 0)$) {$\bullet$};
            \node [red] (B) at ($(current page.south west)+(5, 0)$) {$\bullet$};
            \draw [dashed, thin, gray] (A) -- (B);

        %% Defining the top and the bottom point    
            \node [blue] (top) at ($(A)!0.3!(B)$) {$\bullet$};
            \node [blue] (down) at ($(A)!0.9!(B)$) {$\bullet$};

        %% Defining intermediary points

        %% Creating labels  

        %% Adding explanations
            %Points A & B
                \node[text = green, below right = .025 and .1 of A] {\itshape A};
                \node[text = green, above right = .025 and .1 of B] {\itshape B};
                \draw [dashed, thin, gray] (A) -- (B);

            %Top and Bottom points
                \node[text = green, right = .1 of top] {\itshape top};
                \node[text = green, right = .1 of down] {\itshape down};

        \end{tikzpicture}
    \end{frame}

    \begin{frame}{With one section}
        \begin{tikzpicture}
        [
            overlay, 
            remember picture, 
            inner sep=0pt,  
        ]
        %% Defining points A and B
            \node [red] (A) at ($(current page.north west)+(3, 0)$) {$\bullet$};        
            \node [red] (B) at ($(current page.south west)+(5, 0)$) {$\bullet$};

        %% Defining the top and the bottom point    
            \node [blue] (top) at ($(A)!0.3!(B)$) {$\bullet$};
            \node [blue] (down) at ($(A)!0.9!(B)$) {$\bullet$};


        %% Defining intermediary points
            \node [yellow] (one) at ($(top)!0.5!(down)$) {$\bullet$};

        %% Creating labels  
            \node [font=\Huge\bfseries, text = gray, left =1em of one, anchor= east] {1};
            \node [font=\Large, text = black, right =1em of one, anchor= west] {title of section 1};

        %% Adding explanations
            %Points A & B
            \node[text = green, below right = .025 and .1 of A] {\itshape A};
            \node[text = green, above right = .025 and .1 of B] {\itshape B};
            \draw [dashed, thin, gray] (A) -- (B);

            %Top and Bottom points
            \node[text = green, right = .1 of top] {\itshape top};
            \node[text = green, right = .1 of down] {\itshape down};
        \end{tikzpicture}
    \end{frame}

    \begin{frame}{With two sections}
        \begin{tikzpicture}
        [
            overlay, 
            remember picture, 
            inner sep=0pt,  
        ]
        %% Defining points A and B
            \node [red] (A) at ($(current page.north west)+(3, 0)$) {$\bullet$};        
            \node [red] (B) at ($(current page.south west)+(5, 0)$) {$\bullet$};

        %% Defining the top and the bottom point    
            \node [blue] (top) at ($(A)!0.3!(B)$) {$\bullet$};
            \node [blue] (down) at ($(A)!0.9!(B)$) {$\bullet$};


        %% Defining intermediary points
            \node [yellow] (one) at ($(top)!0.33!(down)$) {$\bullet$};
            \node [yellow] (two) at ($(top)!0.66!(down)$) {$\bullet$};

        %% Creating labels  
            \node [font=\Huge\bfseries, text = gray, left =1em of one, anchor= east] {1};
            \node [font=\Large, text = black, right =1em of one, anchor= west] {title of section 1};

            \node [font=\Huge\bfseries, text = gray, left =1em of two, anchor= east] {2};
            \node [font=\Large, text = black, right =1em of two, anchor= west] {title of section 2};

        %% Adding explanations
            %Points A & B
                \node[text = green, below right = .025 and .1 of A] {\itshape A};
                \node[text = green, above right = .025 and .1 of B] {\itshape B};
                \draw [dashed, thin, gray] (A) -- (B);

            %Top and Bottom points
                \node[text = green, right = .1 of top] {\itshape top};
                \node[text = green, right = .1 of down] {\itshape down};

        \end{tikzpicture}
    \end{frame}

    \begin{frame}{With three sections}
        \begin{tikzpicture}
        [
            overlay, 
            remember picture, 
            inner sep=0pt,  
        ]
        %% Defining points A and B
            \node [red] (A) at ($(current page.north west)+(3, 0)$) {$\bullet$};        
            \node [red] (B) at ($(current page.south west)+(5, 0)$) {$\bullet$};

        %% Defining the top and the bottom point    
            \node [blue] (top) at ($(A)!0.3!(B)$) {$\bullet$};
            \node [blue] (down) at ($(A)!0.9!(B)$) {$\bullet$};


        %% Defining intermediary points
            \node [yellow] (one) at ($(top)!0.25!(down)$) {$\bullet$};
            \node [yellow] (two) at ($(top)!0.50!(down)$) {$\bullet$};
            \node [yellow] (three) at ($(top)!0.75!(down)$) {$\bullet$};

        %% Creating labels  
            \node [font=\Huge\bfseries, text = gray, left =1em of one, anchor= east] {1};
            \node [font=\Large, text = black, right =1em of one, anchor= west] {title of section 1};

            \node [font=\Huge\bfseries, text = gray, left =1em of two, anchor= east] {2};
            \node [font=\Large, text = black, right =1em of two, anchor= west] {title of section 2};

            \node [font=\Huge\bfseries, text = gray, left =1em of three, anchor= east] {3};
            \node [font=\Large, text = black, right =1em of three, anchor= west] {title of section 3};

        %% Adding explanations
            %Points A & B
                \node[text = green, below right = .025 and .1 of A] {\itshape A};
                \node[text = green, above right = .025 and .1 of B] {\itshape B};
                \draw [dashed, thin, gray] (A) -- (B);

            %Top and Bottom points
                \node[text = green, right = .1 of top] {\itshape top};
                \node[text = green, right = .1 of down] {\itshape down};

            %Between 1, 2, 3...
                \path (top) -- node [gray, midway] {x} (one);
                \path (one) -- node [gray, midway] {x} (two);
                \path (two) -- node [gray, midway] {x} (three);
                \path (three) -- node [gray, midway] {x} (down);
        \end{tikzpicture}
    \end{frame}

    \begin{frame}{Intended result with three sections}
        \begin{tikzpicture}
        [
            overlay, 
            remember picture, 
            inner sep=0pt,  
        ]
        %% Defining points A and B
            \node [red] (A) at ($(current page.north west)+(3, 0)$) {};     
            \node [red] (B) at ($(current page.south west)+(5, 0)$) {};

        %% Defining the top and the bottom point    
            \node [blue] (top) at ($(A)!0.3!(B)$) {};
            \node [blue] (down) at ($(A)!0.9!(B)$) {};


        %% Defining intermediary points
            \node [yellow] (one) at ($(top)!0.25!(down)$) {};
            \node [yellow] (two) at ($(top)!0.50!(down)$) {};
            \node [yellow] (three) at ($(top)!0.75!(down)$) {};

        %% Creating labels  
            \node [font=\Huge\bfseries, text = gray, left =1em of one, anchor= east] {1};
            \node [font=\Large, text = black, right =1em of one, anchor= west] {title of section 1};

            \node [font=\Huge\bfseries, text = gray, left =1em of two, anchor= east] {2};
            \node [font=\Large, text = black, right =1em of two, anchor= west] {title of section 2};

            \node [font=\Huge\bfseries, text = gray, left =1em of three, anchor= east] {3};
            \node [font=\Large, text = black, right =1em of three, anchor= west] {title of section 3};

        \end{tikzpicture}
    \end{frame}
\end{document}
  • 1
    Currently all your titles have the same length. You should test if you still like your layout if e.g. section 1 is long, section 2 short, section 3 in the middle. – Ulrike Fischer Nov 27 '16 at 17:52
  • @UlrikeFischer good point - didn't thought of that. The label "title of section x" is actually vertically centered using its west anchor, so it would remain fairly ok with two-lines section name (see example). I think the most important is an even distribution of 1, 2, etc. (i.e. it would appear weirder if there is the same vertical space between section labels, but not numbers) – ebosi Nov 27 '16 at 17:59
  • 1
    Maybe tex.stackexchange.com/a/303968/36296 can help you how to access the total number of sections. But I hope you will find a better solution to access the section names, then I did in this answer. – user36296 Nov 27 '16 at 20:22
  • 1
    @samcarter thanks: it seems similar indeed ! I will try to create something based on this. – ebosi Nov 27 '16 at 21:16
  • What if the presentation has subsections? – cfr Nov 28 '16 at 1:46
4

My understanding is that you are creating a table of contents. Thus a reasonable way is to setup a toc style and include the .toc file.

@samcarter suggests a better way to capture the total number of sections. But I choose a more brutal way to demostrate that one can include .toc several times and achieve various goals.

In https://tex.stackexchange.com/a/260647/51022 I had demostrated a similar method.

\documentclass{beamer}
    \usepackage{tikz}
        \usetikzlibrary{calc}
        \usetikzlibrary{positioning}

\begin{document}

\section{title of section 1}
\section{title of section 2}
\section{title of section 3}
\section{title of section 4}
\section{title of section 5}
\subsection{title of subsection 4-1}

\makeatletter
\def\beamer@endinputifotherversion#1{}
\def\beamer@sectionintoc#1#2#3#4#5{\def\thelastsection{#1}}
\def\beamer@subsectionintoc#1#2#3#4#5#6{}
\def\beamer@subsubsectionintoc#1#2#3#4#5#6#7{}
\def\thelastsection{0}
\@input{\jobname.toc}
\pgfmathsetmacro\n{\thelastsection+1}
\def\beamer@sectionintoc#1#2#3#4#5{
    \path($(top)!#1/\n!(bot)$)
        +(-1,0)node[left,gray,font=\Huge\bfseries]{#1}
        +( 1,0)node[right,   ,font=\Large        ]{#2};
}

\frame{{table of contents}
    \tikz[remember picture,overlay,inner sep=0]{
        \path($(current page.north west)+(3, 0)$)coordinate(A)
             ($(current page.south west)+(5, 0)$)coordinate(B)
             ($(A)!0.3!(B)$)coordinate(top)
             ($(A)!0.9!(B)$)coordinate(bot);
        \@input{\jobname.toc}
    }
}

\makeatother

\end{document}

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.