이렇게 대화형 GAP 세션을 강조하려면 어떻게 해야 합니까?

이렇게 대화형 GAP 세션을 강조하려면 어떻게 해야 합니까?

일부 프로그래밍 언어(내 경우에는 GAP이지만 Python, BASH 또는 대화형 읽기 프롬프트가 있는 다른 언어일 수도 있음)로 스크린 세션을 조판하고 싶다고 가정해 보겠습니다. 내 화면에는 다음과 같은 내용이 표시될 수 있습니다.

gap> for i in [1..10] do
>   Print(i, ":");
> od;
1:2:3:4:5:6:7:8:9:10:
gap> 2^10;
1024
gap> 1/0;
Error, Rational operations: <divisor> must not be zero
not in any function at line 5 of *stdin*
you can replace <divisor> via 'return <divisor>;'
brk> 2^10;
1024
brk>

즉, 명령 프롬프트가 있고 gap>그 후에 사용자가 여러 줄 입력을 입력합니다. 그 다음에는 출력 줄이 나오고 또 다른 프롬프트가 나옵니다 gap>. 이는 명령이 오류를 트리거할 때까지 반복되며, 오류가 발생하면 프롬프트가 로 변경됩니다 brk>.

나는listings패키지 (또는 다른 것)

  1. 프롬프트에 색상을 지정합니다 gap>. >, 및 brk>; 예를 들어, 파란색과 빨간색;
  2. for, do및 와 같은 키워드를 강조 표시합니다 od. 말하자면, 그들을 대담하게 만들어서;
  3. 하지만오직프롬프트로 시작하는 줄의 키워드를 강조 표시하므로 내 명령의 출력 내부가 아닙니다.

마지막 요점은 나에게 문제를 일으키는 것입니다. 나는 그렇게 할 방법을 찾지 못했습니다. 오류 메시지 등에서 , 및 와 같은 단어가 키워드로 강조 표시되면 결과가 상당히 보기 흉한 경우가 많습니다 and.notin

비슷한 질문이 이전에 요청되었지만 내가 찾은 질문 중 정확히 이와 같은 질문을 한 사람은 없었습니다. 내가 원하는 대로 답변을 받았습니다.

기록을 위해 현재 사용하고 있는 언어 정의는 다음과 같습니다.

\lstdefine언어{GAP}{%
    morekeywords=[2]{and,break,continue,do,elif,else,end,fail,false,fi,for,%
        함수,if,in,local,mod,not,od,or,rec,repeat,return,then,true,%
        ~까지,동안},%
    moredelim=[s][\color{파란색}]{gap}{>},%
    moredelim=[s][\color{red}]{brk}{>},%
    %moredelim=*[l][\color{blue}]{gap>},%
    %moredelim=*[l][\color{red}]{brk>},%
    민감함=사실,%
    morecomment=[l]\#,%
    morestring=[b]',%
    morestring=[b]",%
    }%

추신: 내가 원하는 것을 설명하기 위해 위의 예가 어떻게 보이는지 보여주는 이 이미지를 고려하십시오(위에서 설명한 것 외에도 모든 사용자 입력을 기울임꼴로 설정했습니다).

여기에 이미지 설명을 입력하세요

답변1

listings답변은 약 1년 늦었지만 귀하의 모든 요구 사항을 충족한다고 믿습니다.

편집하다: 줄 중간에 나타나는 프롬프트 "키워드"와 관련된 버그를 수정했습니다.

원하는 출력

원하는 출력

얻은 출력

얻은 출력

암호

\documentclass[a4paper]{article}
\usepackage{xcolor}
\usepackage{textcomp}
\usepackage{listings}

\makeatletter

% switch to remember whether a prompt was found on the current line
\newif\ifprompt@GAP@
% switch to flag whether a prompt `keyword' is an bona fide GAP prompt
\newif\iftoolateforprompt@GAP@

% style of GAP keywords
\definecolor{GAPkeywords}{RGB}{077,145,021}
\newcommand\GAPkeywordstyle{\color{GAPkeywords}}

% font shape of GAP input lines 
\newcommand\GAPinputfshape\slshape

\lstdefinelanguage{GAP}
{%
  basicstyle =\ttfamily,
  alsoletter=>,
  morekeywords=[2]{%
    and,break,continue,do,elif,else,end,fail,false,fi,for,function,if,in,%
    local,mod,not,od,or,rec,repeat,return,then,true,until,while,
  },%
  keywordstyle=[2]\Process@GAP@keywords,
  morekeywords=[3]{gap>,>},
  keywordstyle=[3]\Process@GAP@prompt{blue},
  morekeywords=[4]{brk>},
  keywordstyle=[4]\Process@GAP@prompt{red},
  sensitive=true,%
  upquote=true,% <--- for straight single quotes
  showstringspaces=false,
  morecomment=[l]\#,
  morestring=[b]',
  morestring=[b]",
}%

% only highlight keywords if a prompt has occured on the current line
\newcommand\Process@GAP@keywords{\ifprompt@GAP@\GAPkeywordstyle\fi}

\newcommand\Process@GAP@prompt[1]
{%
  \iftoolateforprompt@GAP@%
  \else%
      \color{#1}\upshape% customise the style of your > and gap> prompts here
      \global\prompt@GAP@true%
      \aftergroup\GAPinputfshape% we trigger slanted shape after > or gap>
  \fi%
}

% Hook into InitVarsEOL (some hook executed right after an EOL) to:
% - reset the \ifprompt@GAP@ and \iftoolateforprompt@GAP@ switches
% - reset the font shape to \upshape
\lst@AddToHook{InitVarsEOL}%
{%
  \global\prompt@GAP@false%
  \global\toolateforprompt@GAP@false%
  \upshape%
}

% Hook into PostOutput to signal that a GAP prompt
% can no occur on the current line
\lst@AddToHook{PostOutput}{\global\toolateforprompt@GAP@true}

\makeatother

\begin{document}
\begin{lstlisting}[language=GAP]
gap> for i in [1..10] do
>   Print(i, ":");
> od;
1:2:3:4:5:6:7:8:9:10:
gap> 2^10;
1024
gap> 1/0;
Error, Rational operations: <divisor> must not be zero
not in any function at line 5 of *stdin*
you can replace <divisor> via 'return <divisor>;'
brk> 2^10;
1024
brk>
\end{lstlisting}
\end{document}

답변2

한 가지 단점은 하위 단어가 아닌 전체 단어를 처리한다는 것입니다. 따라서 는 와 od;별개의 단어입니다 od. 이는 극복될 수 있지만 이 MWE에서는 그렇지 않습니다. 원시(형식화되지 않은) 세션 출력을 파일에 복사했습니다.세션.인그리고 거기에서 갔다.

\documentclass[12pt]{article}
\makeatletter%
\let\protectededef\protected@edef
\makeatother%

\parindent 0in
\renewcommand{\encodingdefault}{T1}
\usepackage{color}
\usepackage{readarray}
\usepackage{verbatimbox}
\usepackage{ifthen}
\catcode`^=12
\definecolor{darkgreen}{rgb}{0,0.5,0}
\newcounter{rowindex}\newcounter{wordindex}%

\newcommand\displaysource[1]{%
  \sffamily%
  \readdef{#1}{\x}%
  \setcounter{rowindex}{0}%
  \whiledo{\value{rowindex} < \nrecords}{%
    \addtocounter{rowindex}{1}%
    \getargsC{\csname record\roman{rowindex}\endcsname}%
    \ifthenelse{\equal{\argi}{>}  \OR%
                \equal{\argi}{gap>}  \OR%
                \equal{\argi}{brk>}}%
                {\def\userin{\itshape}}{\def\userin{\upshape}}%
    \setcounter{wordindex}{0}%
    \whiledo{\value{wordindex} < \narg}{%
      \addtocounter{wordindex}{1}%
      \protectededef\thisword{\csname arg\roman{wordindex}\endcsname}%
      \ifthenelse{\equal{\thisword}{gap>}  \OR%
                  \equal{\thisword}{>}}%
        {%
          \upshape\textcolor{blue}{\thisword~}%
        }{%
          \ifthenelse{\equal{\thisword}{brk>}}%
            {%
              \textcolor{red}{brk>~}%
            }{%
              \userin%
              \ifthenelse{\equal{\thisword}{for}  \OR%
                          \equal{\thisword}{in}  \OR%
                          \equal{\thisword}{do}  \OR%
                          \equal{\thisword}{od}  \OR%
                          \equal{\thisword}{od;}}%
              {%
                \ifthenelse{\equal{\userin}{\itshape}}%
                  {%
                    \textcolor{darkgreen}{\thisword~}%
                  }{%
                    \thisword~%
                  }%
              }{%
                \thisword~%
              }
            }%
        }%
    }%
    \\%
  }%
  \rmfamily%
}
\begin{document}

\displaysource{session.in}

\end{document}

여기에 이미지 설명을 입력하세요

관련 정보