1

I am using this answer to produce a transcript. I would like to increment each time I present a speaker, ie Speaker01_01, Speaker02_01, Speaker01_02, Speaker02_02 and so on. Presumably I would use some kind of counter, but cannot see how to adapt the code. The MWE is from the previous answer, rather than my own workings.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xparse}
\usepackage{enumitem}
\setlist[description]{
  font={\sffamily\bfseries},
  labelsep=0pt,
  labelwidth=\transcriptlen,
  leftmargin=\transcriptlen,
}

\newlength{\transcriptlen}

\NewDocumentCommand {\setspeaker} { mo } {%
  \IfNoValueTF{#2}
  {\expandafter\newcommand\csname#1\endcsname{\item[#1:]}}%
  {\expandafter\newcommand\csname#1\endcsname{\item[#2:]}}%
  \IfNoValueTF{#2}
  {\settowidth{\transcriptlen}{#1}}%
  {\settowidth{\transcriptlen}{#2}}%
}

% Easiest to put the longest name last...
\setspeaker{Bob}
\setspeaker{Billy}[Billy Bob]
\setspeaker{xxx}[Xavier Xanadu III]

% How much of a gap between speakers and text?
\addtolength{\transcriptlen}{1em}%

\begin{document}
\begin{description}

  \Bob I'm looking for a package to help with the layout of an
  interview transcript are there any good packages to do such a
  task. If possible could you provide a minimum working example?

  \Billy I'm looking for a package to help with the layout of an
  interview transcript are there any good packages to do such a
  task. If possible could you provide a minimum working example?

  \xxx Perhaps something that aligns the names to the text, and uses a
  columnar layout for the people vs what they said.

\end{description}
\end{document}

This is what I'm trying to achieve:

Speaker01_01: Blah Blah Blah
Speaker02_01: Blah Blah Blah
Speaker01_02: Blah Blah Blah
Speaker02_02: Blah Blah Blah

So: {speakername}{appendnumber}: {words spoken}


Using the answer, I'm getting an extraneous space at 10.

enter image description here

  • So instead of names you want just some number displayed? I'm confused. Can you please exactly explain what the syntax should look like and what it should produce? Something like \setspeaker{Joey} and then \Joey should expand to Speaker01:? – Skillmon May 15 at 7:44
  • It doesn't matter what the name is P01, Speaker01, Speaker02, but every time the person is in the transcript, it should increment by 1, ie, Speaker01_01, Speaker01_02 (or whatever the speaker's name is)....I thought it was pretty clear... So no, i'm not interested in changing speakers names to codes, just adding a number to the end of the name...is that clear? – Frank Zafka May 15 at 7:47
  • 1
    ahhhh. Now I understood. – Skillmon May 15 at 8:15
2

I made a few changes to your code, most notably you don't have to put the longest name last anymore (it is checked which name is the longest).

The width of the speakers on first run is the width of the longest speaker plus the width required for a 0 and the skip between the speakers and their text. On consecutive runs the biggest number will be taken into account, too, so the width is set as big as required. You can however set an upper limit with the length \speakerwidthmax (I've set it to 4cm here).

EDIT: I've added the macro \resetspeakers that resets all counters back to 0.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xparse}
\usepackage{enumitem}
\setlist[description]{
  font=\speakerfont,
  labelsep=0pt,
  labelwidth=\speakerwidth,
  leftmargin=\speakerwidth,
}

\newlength{\speakerlongest}
\newlength{\speakerskip}
\newlength{\speakerwidthmax}

% distance between speakers and text
\setlength{\speakerskip}{1em}
% maximum width for speaker names
\setlength{\speakerwidthmax}{4cm}

\newcommand*\speakerfont{\sffamily\bfseries}
\newcommand*\speakerwidth
  {%
    \ifdim\speakerlongest>\speakerwidthmax
      \speakerwidthmax
    \else
      \speakerlongest
    \fi
  }
\newcommand*\printscriptline[2]
  {%
    \begingroup
    \setbox0\hbox{#2, \csname the#1count\endcsname:\hskip\speakerskip}%
    \usebox0%
    \ifdim\speakerlongest<\wd0
      \global\setlength\speakerlongest{\wd0}%
    \fi
    \endgroup
  }
\newcommand*\speakerlongestset[1]
  {%
    \begingroup
    \settowidth{\dimen0}{\speakerfont#1, 0:\hskip\speakerskip}%
    \expandafter\endgroup
    \expandafter\speakerlongestsetAUX\expandafter{\the\dimen0}%
  }
\newcommand*\speakerlongestsetAUX[1]
  {%
    \ifdim\speakerlongest<#1
      \setlength\speakerlongest{#1}%
    \fi
  }
\makeatletter
\AtEndDocument
  {%
    \write\@auxout
      {\global\protect\setlength\protect\speakerlongest{\the\speakerlongest}}%
  }
\newcommand*\resetspeakers
  {%
    \begingroup
    \@for\speaker:=\speakerslist\do{\setcounter{\speaker count}{0}}%
    \endgroup
  }
\let\speakerslist\empty
\makeatother

\NewDocumentCommand {\setspeaker} { mo } {%
  \newcounter{#1count}%
  \ifx\speakerslist\empty
    \def\speakerslist{#1}%
  \else
    \edef\speakerslist{\unexpanded\expandafter{\speakerslist,#1}}%
  \fi
  \IfNoValueTF{#2}
    {%
      \expandafter\newcommand\csname#1\endcsname
        {%
          \refstepcounter{#1count}%
          \item[\printscriptline{#1}{#1}]%
        }%
      \speakerlongestset{#1}%
    }%
    {%
      \expandafter\newcommand\csname#1\endcsname
        {%
          \refstepcounter{#1count}%
          \item[\printscriptline{#1}{#2}]%
        }%
      \speakerlongestset{#2}%
    }%
}

% Easiest to put the longest name last...
\setspeaker{xxx}[Xavier Xanadu III]
\setspeaker{Billy}[Billy Bob]
\setspeaker{Bob}

\begin{document}
\begin{description}

  \Bob I'm looking for a package to help with the layout of an
  interview transcript are there any good packages to do such a
  task. If possible could you provide a minimum working example?

  \Billy I'm looking for a package to help with the layout of an
  interview transcript are there any good packages to do such a
  task. If possible could you provide a minimum working example?

  \xxx Perhaps something that aligns the names to the text, and uses a
  columnar layout for the people vs what they said.

  \Bob This is my second line!

  \resetspeakers
  \xxx This is my second line!
  \xxx This is my second line!
  \xxx This is my second line!
  \xxx This is my second line!
  \xxx This is my second line!
  \xxx This is my second line!
  \xxx This is my second line!
  \xxx This is my second line!
  \xxx This is my second line!
\end{description}
\end{document}

enter image description here

  • That appears to be it. I was never going to cargo cult my way to it. :) Thanks. – Frank Zafka May 15 at 8:58
  • I'm getting an extraneous space after 10 in my version. I believe it's to do with the length of the name? I'll add a screenshot to the question... – Frank Zafka May 15 at 9:29
  • @Frank_Zafka run it twice. If that's still the case and it bothers you, increase the value of \speakerwidthmax. On the first run the maximum number is not known yet, so the space is assumed to be only a single digit. On second run the width is set to the widest encountered during the first run. – Skillmon May 15 at 10:16
  • Actually I tried that. It does bother me, because it just doesn't look as neat as being flush. Increasing \speakerwidthmax doesn't appear to change the behaviour. – Frank Zafka May 15 at 10:26
  • Can I be annoying and ask how to reset the counter. I have multiple transcripts in the same document, and I'd love to issue a reset back to 1. – Frank Zafka May 15 at 10:41
1

The label width can be set at end document and you need just a rerun of LaTeX to get it right (being warned if it is needed):

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xparse}
\usepackage{enumitem}

\setlist[description]{
  font={\sffamily\bfseries},
  labelsep=0pt,
  labelwidth=\transcriptlen,
  leftmargin=\transcriptlen,
}

\newlength{\transcriptlen}

\ExplSyntaxOn

\NewDocumentCommand{\setspeaker}{ mO{#1} }
 {% if the optional argument is missing, default it to the first argument
  \zafka_setspeaker:nn { #1 } { #2 }
 }

\dim_new:N \l_zafka_width_dim
\dim_new:N \g_zafka_width_dim

\cs_new_protected:Nn \zafka_setspeaker:nn
 {
  % allocate a new counter
  \int_new:c { g_zafka_#1_int }
  % define a command
  \cs_new_protected:cpn {#1}
   {
    % increase the counter
    \int_gincr:c { g_zafka_#1_int }
    % measure the label width
    \settowidth{\l_zafka_width_dim}{{\sffamily\bfseries #2,~\int_use:c { g_zafka_#1_int }}\quad}
    % update the maximum width
    \dim_gset:Nn \g_zafka_width_dim
     {
      \dim_max:nn { \g_zafka_width_dim } { \l_zafka_width_dim }
     }
    % add the item
    \item[#2,~\int_use:c { g_zafka_#1_int }]
   }
 }

\AtEndDocument
 {
  % if the maximum width is different from \transcriptlen, issue a warning
  \dim_compare:nF { \transcriptlen = \g_zafka_width_dim }
   {
    \msg_warning:nn { zafka } { rerun }
   }
  \iow_shipout:cx { @auxout }
   {% save the maximum width collected so far
    \global\transcriptlen=\dim_eval:n { \g_zafka_width_dim } \relax
   }
 }

\msg_new:nnn { zafka } { rerun }
 {
  Label~width~in~transcript~has~changed.~Rerun~LaTeX.
 }

\ExplSyntaxOff

\setspeaker{Bob}
\setspeaker{Billy}[Billy Bob]
\setspeaker{xxx}[Xavier Xanadu III]

\begin{document}
\begin{description}

  \Bob I'm looking for a package to help with the layout of an
  interview transcript are there any good packages to do such a
  task. If possible could you provide a minimum working example?

  \Billy I'm looking for a package to help with the layout of an
  interview transcript are there any good packages to do such a
  task. If possible could you provide a minimum working example?

  \Bob I'm looking for a package to help with the layout of an
  interview transcript are there any good packages to do such a
  task. If possible could you provide a minimum working example?

  \xxx Perhaps something that aligns the names to the text, and uses a
  columnar layout for the people vs what they said.

  \Bob I'm looking for a package to help with the layout of an
  interview transcript are there any good packages to do such a
  task. If possible could you provide a minimum working example?

  \Billy I'm looking for a package to help with the layout of an
  interview transcript are there any good packages to do such a
  task. If possible could you provide a minimum working example?

  \xxx Perhaps something that aligns the names to the text, and uses a
  columnar layout for the people vs what they said.

\end{description}
\end{document}

enter image description here

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.