First, I will try to explain why fully answering your answer is quite difficult.
\l@section
and friends are commands that define the appearance of various items in the table of contents, and at this point LaTeX does not have the means to know in which section or subsection we are.
If you want to influence the way they are processed, you should do it at a higher level, i.e. in the definition of the sectioning commands. All lower divisions (starting from section downward) are defined in LaTeX2e using the \@startsection
command which, obviously, you would be very unwise to try to modify. You can have a look at it in the latex.ltx file.
Besides, LaTeX processes these document divisions when it sees them – so we have means to know whether some section or subsection is the first one (or second one, etc.), but we have no easy way of finding out whether it is the last one. If you wanted to do that, you would need to ask LaTeX to write the number of the counter before each reset to a separate file, then retrieve it in a second run of LaTeX so as to use it. This, for instance, is how tables of contents are written (and why they need two compilations).
The solution I am proposing will try to solve the first problem [edit: and the second one too]. We are going to redefine the \subsection
command so that the first subsection will always typeset || before itself, and each subsection will end with a semi-colon in the table of contents [edit: except the last subsection of each section]. We will also define a command that takes care of formatting the number of the subsection.
% Used for playing around with the semicolons
\usepackage{refcount}
\makeatletter
\renewcommand{\tableofcontents}{\noindent\@starttoc{toc}}
\renewcommand{\l@section}[2]{#1}% No other modification needed here
\renewcommand{\l@subsection}[2]{#1}% No other modification needed here
\renewcommand{\numberline}[1]{\textbf{#1}.~}
% Create a new command for italic numbers in the TOC
\newcommand{\numbersubsec}[1]{\textit{#1}.~}
% Create a new counter for the semicolons. It is reset at every \section
\newcounter{cntsemicolon}[section]
% Save the old definition of \subsection under the name \oldsubsection
\let\oldsubsection=\subsection
% Overwrite \subsection
\renewcommand{\subsection}[1]{%
% Increase the subsection counter, as it will not be increased automatically + Increase the semicolon counter
\refstepcounter{subsection}%
\refstepcounter{cntsemicolon}\label{mycounterref@\thesection}%
% Check whether this is the first subsection or not
\ifnum\value{subsection}<2%
% If the value of the subsection counter is <2, it is the first subsection
% Add the subsection to the TOC with the extra || (\textbar) and ;
\addcontentsline{toc}{subsection}{\unskip~\textbar\textbar~\numbersubsec{\thesubsection}#1%
% If the value of the subsection counter is not equal to the maximum value of the semicolon counter for the section, add a semicolon
\ifnum\value{subsection}=\number\numexpr\getrefnumber{mycounterref@\number\value{section}}~\textbar\textbar~\unskip\else;\fi}%
\else%
% Else (i.e. if it is not the first subsection)
% Add the subsection to the TOC with ; at the end
\addcontentsline{toc}{subsection}{\numbersubsec{\thesubsection}#1%
% If the value of the subsection counter is not equal to the maximum value of the semicolon counter for the section, add a semicolon
\ifnum\value{subsection}=\number\numexpr\getrefnumber{mycounterref@\number\value{section}}~\textbar\textbar~\unskip\else;\fi}%
\fi%
% Create a subsection heading in the main text
% The \hspace command create the white-space between the number and the text.
% Its value is copied from the original \subsection command.
\oldsubsection*{\thesubsection\hspace{1.5ex \@plus .2ex}#1}}
\makeatother
Note: we use the starred version of \subsection
, which does NOT increase the counter and does not add anything to the TOC (it also does not set any page headers, so you might need to set them manually inside the new command, too). This way, it is possible to tamper with the data that will actually be added to the table of contents.
As you can see, after three runs, it will result in something like:
1. Section one || 1.1. Subsection one; 1.2. Subsection two || 2. Section two 3. Section three
Edit: Added a solution to the semicolon issue using @egreg's answer to this post.
Edit 2: Added the || before the next section instead of the semicolon too, as I just noticed they were there in the OP's question.