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}
  • Please provide the document, that causes this error, not just fragments – user31729 Jun 2 '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 3 '16 at 8:48
3

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

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

should work as expected.

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.