3

According to listings - use different style for normal comments /* and doxygen comments /**
I used listings package to set style for /** Doxygen comments */ as user defined delimiter

moredelim = [s][\color{ForestGreen}]{/**}{*/}

This own delimiter should contain its own "keywords" that should not be messed with processed language keywords. Such "keywords" could be Doxygen's annotations for C++ code:

  • C++ keywords should not be highlighted inside Doxygen delimiter /** */,
    /** @author int */
  • Doxygen "keywords" should not be highlighted outside Doxygen delimiter
    @author int

File test.tex tests also strings, comments, other own delimiter.

\begin{MyCode}
/**
 * @author HERE
 * @param HERE
 * @return HERE
 * int float void not_here
 */
int main(void) {
  float f = @param + @return + not_here;
  string s = "@param @return not here";
  int @author = not_here;
  return 0;
}
#pragma not here @param @return
/* @author @param not here */
\end{MyCode}

Using literate highlights annotations everywhere.

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[svgnames]{xcolor}
\usepackage[scaled=0.84]{beramono}
\usepackage{listings}

\lstnewenvironment{MyCode}
{\lstset{language=C++,
literate={@param}{\bfseries @param}1
    {@return}{\bfseries @return}1
    {@author}{\bfseries @author}1,
basicstyle=\ttfamily,
keywordstyle=\bfseries,
identifierstyle=\color{blue},
stringstyle=\color{magenta},
commentstyle=\color{olive},
moredelim=[s][\color{ForestGreen}]{/**}{*/},
moredelim=[l][\color{red}]{\#pragma},
frame=single,showstringspaces = false,columns=flexible}
}{}

\begin{document}
\input{test}
\end{document}

For some unknown reason it also removes spaces but it's not the main problem.

Literate for Doxygen annotations

The similar problem may appear if we want highlight something else inside pragma delimiter

moredelim=[l][\color{red}]{\#pragma},

or inside normal strings and comments.

0

2 Answers 2

3

My second solution is not exactly what I wanted.

I should find whether I'm inside my moredelim or not. Instead I check the font properties specific for that moredelim.

Test against font family

  1. I make Doxygen comment the only style which uses \sffamily

    moredelim=[s][\color{ForestGreen}\sffamily]{/**}{*/}, %doxygen comment

  2. Inside literate rule I use a conditional against \sffamily

Complete example

doc.tex

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[svgnames]{xcolor}
\usepackage[scaled=0.84]{beramono}
\usepackage{listings}
\usepackage{pdftexcmds}

\makeatletter
\newcommand{\MyBoldSf}[1]{%
\ifnum\pdf@strcmp{\f@family}{\sfdefault}=\z@%
{\color{green!30!black}\bfseries #1 }%extra space
\else%
#1 %extra space
\fi%
}%
\makeatother

\lstnewenvironment{MyCode}
{\lstset{language=C++,
literate={@param}{\MyBoldSf{@param}}1
   {@return}{\MyBoldSf{@return}}1
   {@author}{\MyBoldSf{@author}}1,
basicstyle=\ttfamily,
keywordstyle=\bfseries,
%identifierstyle=\color{blue},
stringstyle=\color{magenta},
commentstyle=\color{olive},
moredelim=[s][\color{ForestGreen}\sffamily]{/**}{*/}, %doxygen comment
moredelim=[l][\color{red}]{\#pragma}, %preprocessor
frame=single,showstringspaces = false,columns=flexible}
}{}

\begin{document}
\input{test}
\end{document}

test.tex

\begin{MyCode}
/**
 * @author HERE
 * @param HERE
 * @return HERE
 * int float void not_here
 */
int main(void) {
  float f = @param + @return + not_here;
  string s = "@param @return not here";
  int @author = not_here;
  return 0;
}
#pragma not here @param @return
/*@author @param not here  */
\end{MyCode}

enter image description here

Problems

  1. I didn't want to have Doxygen Comments as \sffamily. I want them to remain \ttfamily like the rest of code. I would rather test against moredelim or unique property like font color (ForestGreen in the example)

  2. I still have problems with extra spaces. With the above solution I get extra space inside normal comment or a string. If i remove space from the solution, I get no space when command \MyBoldSf is used.

Test against font color

I've asked a question about conditional against font color. According to given answers I have written command to change test with specific color

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[svgnames]{xcolor}
\usepackage[scaled=0.84]{beramono}
\usepackage{listings}

\makeatletter
\newcommand{\MyChange}[2]{%
  \extractcolorspec{.}\MyChange@CurrentColor
  \extractcolorspec{#2}\MyChange@TestColor
  \ifx\MyChange@CurrentColor\MyChange@TestColor
    {\bfseries\color{green!33!black} #1 }%
  \else
    {#1 }%
  \fi%
}
\makeatother

\lstnewenvironment{MyCode}
{\lstset{language=C++,
literate={@param}{\MyChange{@param}{ForestGreen}}1
   {@return}{\MyChange{@return}{ForestGreen}}1
   {@author}{\MyChange{@author}{ForestGreen}}1,
basicstyle=\ttfamily,
keywordstyle=\bfseries,
identifierstyle=\color{blue},
stringstyle=\color{magenta},
commentstyle=\color{olive},
moredelim=[s][\color{ForestGreen}]{/**}{*/}, %doxygen comment
moredelim=[l][\color{red}]{\#pragma}, %preprocessor
frame=single,showstringspaces = false,columns=flexible}
}{}

\begin{document}
\input{test2}
\end{document}

Where test2.tex is

\begin{MyCode}
/**
 * @author BOLD HERE
 * @param BOLD HERE
 * @return BOLD HERE
 * int float void not_here
 */
int main(void) {
  float f = @param + @return + here_not_bold;
  string s = "@param @return here not bold";
  int @author = here_not_bold;
  return 0;
}
#pragma not here @param @return
/*@author @param not here  */
#pragma omp parallel private(id)
\end{MyCode}

enter image description here

Test against font color (more general)

Command MyChange can be used for replacing words within different colors

For example, there could be added special words for #pragma delim

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[svgnames]{xcolor}
\usepackage[scaled=0.84]{beramono}
\usepackage{listings}

\makeatletter
\newcommand{\MyChange}[3]{%
  \extractcolorspec{.}\MyChange@CurrentColor
  \extractcolorspec{#2}\MyChange@TestColor
  \ifx\MyChange@CurrentColor\MyChange@TestColor
    {\bfseries\color{#3} #1}%
  \else
    {#1}%
  \fi%
}
\makeatother

\lstnewenvironment{MyCode}
{\lstset{language=C++,
literate={@param}{\MyChange{@param}{ForestGreen}{green!33!black} }1
   {@return}{\MyChange{@return}{ForestGreen}{green!33!black} }1
   {@author}{\MyChange{@author}{ForestGreen}{green!33!black} }1
   {omp}{\MyChange{omp}{red}{red!66!black} }1
   {parallel}{\MyChange{parallel}{red}{red!66!black} }1
   {private}{\MyChange{private}{red}{red!66!black} }1,
basicstyle=\ttfamily,
keywordstyle=\bfseries,
identifierstyle=\color{blue},
stringstyle=\color{magenta},
commentstyle=\color{olive},
moredelim=[s][\color{ForestGreen}]{/**}{*/}, %doxygen comment
moredelim=[l][\color{red}]{\#pragma}, %preprocessor
frame=single,showstringspaces = false,columns=flexible}
}{}

\begin{document}
\input{test2}
\end{document}

For the same test2.tex I get

enter image description here

2

My first solution for formatting Annotation inside Doxygen is not autamatic. It requires manual edition of source code.

While defining MyCode I set escapechar to enable formatting of the desired words

\lstnewenvironment{MyCode}
{\lstset{language=C++,
escapechar=~,
...
}{}

Inside MyCode pasted source is manually extended with formatting

\begin{MyCode}
~\bfseries{}\ttfamily{}@param~ 
\end{MyCode}

Complete example

Main document doc.tex contains definition of the command \DoxAnno which will be used for highlighting

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[svgnames]{xcolor}
\usepackage[scaled=0.84]{beramono}
\usepackage{listings}

\newcommand{\DoxAnno}[1]{\ttfamily{\bfseries{\textcolor{green!33!black}{#1}}}} %Doxygen Annotation

\lstnewenvironment{MyCode}
{\lstset{language=C++,
escapechar=~,
basicstyle=\ttfamily,
keywordstyle=\bfseries,
identifierstyle=\color{blue},
stringstyle=\color{magenta},
commentstyle=\color{olive},
moredelim=[s][\color{ForestGreen}]{/**}{*/}, %doxygen comment
moredelim=[l][\color{red}]{\#pragma}, %preprocessor
frame=single,showstringspaces = false,columns=flexible}
}{}

\begin{document}
\input{testEscape}
\end{document}

testEscape.tex

\begin{MyCode}
/**
 * ~\DoxAnno{@author}~ HERE
 * ~\DoxAnno{@param}~ HERE
 * ~\DoxAnno{@return}~ HERE
 * int float void not_here
 */
int main(void) {
  float f = @param + @return + not_here;
  string s = "@param @return not here";
  int @author = not_here;
  return 0;
}
#pragma not here @param @return
/* @author @param not here */
\end{MyCode}

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.