\lstdefinelanguage 无法处理关键字 #if、#endif、

\lstdefinelanguage 无法处理关键字 #if、#endif、

我需要在我的 LaTeX 文档中插入 C 代码片段。因此我定义了一个 C 代码语言语法高亮:

\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},
}

如您所见,我希望大多数关键字为浅蓝色。但是关键字#if#endif#else应该是红色。我在 StackOverflow 上看到,新关键字中的特殊字符可能会引起麻烦。显然我需要插入代码行:

alsoletter = {<your special character here>}

或者:

alsodigit = {<your special character here>}

让它工作。我尝试了两种方法#角色,但都没有成功。我收到以下错误:

\lstlang@customc$ 定义中的参数编号非法。

对于其他字符(例如!),它可以正常工作。我可以创建特殊关键字,例如!if!else!endif,并将它们涂成红色。但我无法让它对#if#else和起作用#endif

编辑:这里有一个完整的测试文档,说明了这个问题:

\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}

答案1

在 LaTeX 中#是一个特殊字符,您需要对其进行转义:

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

应该可以按预期工作。

相关内容