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}