3

I need to insert C-code snippets in my LaTeX document. Therefore I define a C-code language syntax highlighting:

\usepackage[utf8]{inputenc}
\usepackage{listings}
\usepackage{color}


\definecolor{myBlue}{rgb}{0.5,0.5,1}
\definecolor{myLightBlue}{rgb}{0.35,0.6,0.8}
\definecolor{myBlack}{rgb}{0,0,0}
\definecolor{myGreen}{rgb}{0.1,0.6,0.2}
\definecolor{myGray}{rgb}{0.5,0.5,0.5}
\definecolor{myLightgray}{rgb}{0.95,0.95,0.95}
\definecolor{myMauve}{rgb}{0.58,0,0.82}

\lstdefinelanguage{customc}{
    language=C,
    backgroundcolor = \color{myLightgray},
    basicstyle=\scriptsize\ttfamily\color{myBlack},
    keywordstyle=\color{myLightBlue},
    keywordstyle=[2]\color{red},
    commentstyle=\scriptsize\ttfamily\color{myGreen},
    morekeywords={RequirePackage,ProvidesPackage},
    % alsoletter = {#},
    alsodigit = {#},
    keywords=[2]{#if,#endif,#else},
}

As you can see, I want most keywords to be light blue. But the keywords #if, #endif and #else should be red. I read on StackOverflow that special characters in new keywords can cause troubles. Apparently I need to insert the code lines:

alsoletter = {<your special character here>}

or:

alsodigit = {<your special character here>}

to get it working. I tried both approaches for the # character, but without success. I get the following error:

Illegal parameter number in definition of \lstlang@customc$.

For other characters - like !- it works just fine. I can create special keywords like !if, !else and !endif, and color them red. But I don't get it working for #if, #else and #endif.

EDIT: Here is a complete test document that illustrates the issue:

\documentclass[a4paper,11pt]{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage{listings}
\usepackage{color}
\usepackage{geometry}
\geometry{
    a4paper,
    total={170mm,257mm},
    left=20mm,
    top=20mm,
    hmarginratio=1:1,
}


\definecolor{myBlue}{rgb}{0.5,0.5,1}
\definecolor{myLightBlue}{rgb}{0.35,0.6,0.8}
\definecolor{myBlack}{rgb}{0,0,0}
\definecolor{myGreen}{rgb}{0.1,0.6,0.2}
\definecolor{myGray}{rgb}{0.5,0.5,0.5}
\definecolor{myLightgray}{rgb}{0.95,0.95,0.95}
\definecolor{myMauve}{rgb}{0.58,0,0.82}

\lstdefinelanguage{customc}{
    language=C,
    backgroundcolor = \color{myLightgray},
    basicstyle=\scriptsize\ttfamily\color{myBlack},
    keywordstyle=\color{myLightBlue},
    keywordstyle=[2]\color{red},
    commentstyle=\scriptsize\ttfamily\color{myGreen},
    morekeywords={RequirePackage,ProvidesPackage},
    %
    % The special highlighting works for '!if', '!endif' and '!else'
    % But it doesn't work for '#if', '#endif' and '#else'.
    alsoletter = {!},
    keywords=[2]{!if,!endif,!else},
}

\lstdefinestyle{myCustomc}{
    language = customc,
    % keywordstyle = \color{myMauve},
}

\lstset{escapechar=@,style=myCustomc}

\begin{document}
    This is a C-code snippet:

    \begin{lstlisting}

        void SystemInit(void)
        {
            /*--------------------------------------------------------------------------*/
            /*|                             FPU                                        |*/
            /*--------------------------------------------------------------------------*/
            /* The macros __FPU_PRESENT and __FPU_USED are set through the command line */
            /* options when invoking the gcc compiler. It is possible that the IDE      */
            /* does not represent their values correctly while coding.                  */
            #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
            /* set CP10 and CP11 Full Access */
            SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
            #endif

            /*--------------------------------------------------------------------------*/
            /*|                        RCC clock config                                |*/
            /*--------------------------------------------------------------------------*/
            /* Reset the RCC clock configuration to the default reset state             */

            RCC->CR |= (uint32_t)0x00000001;      /* Set HSION bit                      */
            RCC->CFGR = 0x00000000;               /* Reset CFGR register                */
            RCC->CR &= (uint32_t)0xFEF6FFFF;      /* Reset HSEON, CSSON and PLLON bits  */
            RCC->PLLCFGR = 0x24003010;            /* Reset PLLCFGR register             */
            RCC->CR &= (uint32_t)0xFFFBFFFF;      /* Reset HSEBYP bit                   */
            RCC->CIR = 0x00000000;                /* Disable all interrupts             */

            /*--------------------------------------------------------------------------*/
            /*|                        External S(D)RAM                                |*/
            /*--------------------------------------------------------------------------*/
            /* This function configures the external memories (SRAM/SDRAM)              */
            /* This SRAM/SDRAM will be used as program data memory (including heap      */
            /* and stack).                                                              */
            #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
            SystemInit_ExtMemCtl();
            #endif

            /*--------------------------------------------------------------------------*/
            /*|                        VECTOR TABLE location                           |*/
            /*--------------------------------------------------------------------------*/
            /* The initial Vector Table address SCB->VTOR equals the Boot Base Address  */
            /* which is selected by the BOOT pin. The initial Vector Table location     */
            /* affects the boot behaviour (where the CPU makes its first jump...).      */
            /* Once the program is running, the Vector Table can be relocated. That is  */
            /* what the code below is doing.                                            */
            #ifdef VECT_TAB_SRAM
            SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Relocation to Internal SRAM */
            #else
            SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Relocation in Internal FLASH */
            #endif
        }

    \end{lstlisting}

    Now the document ends.

\end{document}
K.Mulier
  • 347
  • Please provide the document, that causes this error, not just fragments –  Jun 02 '16 at 20:12
  • Hi @ChristianHupfer , thank you very much for your help. I have added a complete example to illustrate the problem. – K.Mulier Jun 03 '16 at 08:48

1 Answers1

3

In LaTeX # is a special character and you need to escape it:

alsoletter = {\#},
keywords=[2]{\#if,\#endif,\#else},

should work as expected.

Bordaigorl
  • 15,135