The difficulty here is to know which persons will appear later on but the list of characters have to done before.
I am using the \label approach here and checking if the label is given, otherwise the person is not listed.
A new person is defined with \NewPerson{foo}, which automatically defines \foox and adds the code to check for label existence etc.
Now, the Command \DisplayPersons loops through all defined persons and stores the local ones, loops again through this smaller list of persons and applies \displayindividualperson which can be changed to personal preferences.
The macros \PostPersonlist and \personlistheader can be configured to provide other styles.
Note: As with any \label based approach at least two runs of compilations are necessary
\documentclass{scrartcl}
\usepackage{refcount}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \g_luke_listofpersons_seq
\seq_new:N \l_luke_listofpersons_seq
\NewDocumentCommand{\addperson}{m}{%
\seq_gput_right:Nn \g_luke_listofpersons_seq {#1}
\seq_gremove_duplicates:N \g_luke_listofpersons_seq
}
\NewDocumentCommand{\addpersonlocal}{m}{%
\seq_gput_right:Nn \l_luke_listofpersons_seq {#1}
}
\cs_new:Npn \IfPersonCalledAlreadyF #1#2 {%
\seq_if_in:NnF \l_luke_listofpersons_seq {#1} {#2}
}
\NewDocumentCommand{\DisplayPersons}{}{%
\seq_clear:N \l_luke_listofpersons_seq
\group_begin:
\seq_clear:N \l_tmpa_seq
\seq_map_inline:Nn \g_luke_listofpersons_seq {%
\IfRefUndefinedExpandable{##1\thesection}{}{
\seq_put_right:Nn \l_tmpa_seq {\displayindividualperson{##1}}
}
}
\seq_if_empty:NF \l_tmpa_seq {
\PrePersonList
\seq_use:Nn \l_tmpa_seq {,~}
\PostPersonList
}
\group_end:
}
\ExplSyntaxOff
\NewDocumentCommand{\PostPersonList}{}{%
\bigskip%
}
\NewDocumentCommand{\displayindividualperson}{m}{%
\textbf{#1}%
}
\NewDocumentCommand{\PrePersonList}{}{%
{\large \bfseries Persons in Section \thesection}
}
\makeatletter
\NewDocumentCommand{\NewPerson}{m}{%
% Add this person to the global list
\addperson{#1}%
% Now define the personal \...x command
\expandafter\NewDocumentCommand\csname #1x\endcsname{+m}{%
%Check if the person has been called in the local section already
\IfPersonCalledAlreadyF{#1}{%
\addpersonlocal{#1}
% Add the personal to the local list, i.e. per section
% Check whether the label has been defined already
\protected@edef\@currentlabel{\thesection.#1}\label{#1\thesection}
}%
\textsc{#1:} ##1%
}% End of the \...x command
}% End of \NewPerson
\makeatother
\NewPerson{tom}
\NewPerson{frodo}
\NewPerson{Gandalf}
\begin{document}
\section{In the supermarket}
\DisplayPersons
\tomx{Hi, I'm Tom!}
\frodox{Hi, I'm Frodo!}
\section{At TeX.SE}
\DisplayPersons
\frodox{Hi, I'm Frodo!}
\frodox{I am going to Mordor}
\Gandalfx{Cast the ring into the fire!}
\tomx{Waiting for Godot}
\end{document}

Update with hightlighting
\documentclass{scrartcl}
\usepackage{xcolor}
\usepackage{refcount}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \g_luke_listofpersons_seq
\seq_new:N \l_luke_listofpersons_seq
\NewDocumentCommand{\addperson}{m}{%
\seq_gput_right:Nn \g_luke_listofpersons_seq {#1}
\seq_gremove_duplicates:N \g_luke_listofpersons_seq
}
\NewDocumentCommand{\addpersonlocal}{m}{%
\seq_gput_right:Nn \l_luke_listofpersons_seq {#1}
}
\cs_new:Npn \IfPersonCalledAlreadyF #1#2 {%
\seq_if_in:NnF \l_luke_listofpersons_seq {#1} {#2}
}
\NewDocumentCommand{\DisplayPersons}{}{%
\seq_clear:N \l_luke_listofpersons_seq
\group_begin:
\seq_clear:N \l_tmpa_seq
\seq_map_inline:Nn \g_luke_listofpersons_seq {%
\IfRefUndefinedExpandable{##1\thesection}{}{
\seq_put_right:Nn \l_tmpa_seq {\use:c{##1h}}
}
}
\seq_if_empty:NF \l_tmpa_seq {
\PrePersonList
\seq_use:Nn \l_tmpa_seq {,~}
\PostPersonList
}
\group_end:
}
\ExplSyntaxOff
\NewDocumentCommand{\PostPersonList}{}{%
\bigskip%
}
\NewDocumentCommand{\displayindividualperson}{m}{%
\textbf{#1}%
}
\NewDocumentCommand{\PrePersonList}{}{%
{\large \bfseries Persons in Section \thesection}
}
\makeatletter
\NewDocumentCommand{\NewPerson}{m+m}{%
% Add this person to the global list
\addperson{#1}%
% Now define the personal \...x command
\expandafter\NewDocumentCommand\csname #1x\endcsname{+m}{%
%Check if the person has been called in the local section already
\IfPersonCalledAlreadyF{#1}{%
\addpersonlocal{#1}
% Add the personal to the local list, i.e. per section
% Check whether the label has been defined already
\protected@edef\@currentlabel{\thesection.#1}\label{#1\thesection}
}%
\textsc{#1:} ##1%
}% End of the \...x command
\expandafter\NewDocumentCommand\csname #1h\endcsname{}{%
#2{#1}%
}
}% End of \NewPerson
\makeatother
\NewPerson{tom}{\colorbox{green}}
\NewPerson{frodo}{\colorbox{yellow}}
\NewPerson{Gandalf}{\fcolorbox{yellow}{yellow!60!blue}}
\begin{document}
\section{In the supermarket}
\DisplayPersons
\tomx{Hi, I'm Tom!}
\frodox{Hi, I'm Frodo!}
\section{At TeX.SE}
\DisplayPersons
\frodox{Hi, I'm Frodo!}
\frodox{I am going to Mordor}
\Gandalfx{Cast the ring into the fire!}
\tomx{Waiting for Godot}
\end{document}

labelmechanism, i.e. store where the name is referred and read the information to get information what will come up later on. – Mar 05 '17 at 18:03