\lst@NormedDef works like\def (without any parameters!) but normalizes the replacement text by making all characters lower case and stripping off spaces.
517\def\lst@NormedDef#1#2{\lowercase{\edef#1{\zap@space#2 \@empty}}}
\lst@NormedNameDef works like \global\@namedef (again without any parameters!) but normalizes both the macro name and the replacement text.
518\def\lst@NormedNameDef#1#2{%
519 \lowercase{\edef\lst@temp{\zap@space#1 \@empty}%
520 \expandafter\xdef\csname\lst@temp\endcsname{\zap@space#2 \@empty}}}
\lst@GetFreeMacro Initialize\@tempcntaand\lst@freemacro, . . .
521\def\lst@GetFreeMacro#1{%
522 \@tempcnta\z@ \def\lst@freemacro{#1\the\@tempcnta}%
523 \lst@GFM@}
. . . and either build the control sequence or advance the counter and continue.
524\def\lst@GFM@{%
525 \expandafter\ifx \csname\lst@freemacro\endcsname \relax
526 \edef\lst@freemacro{\csname\lst@freemacro\endcsname}%
527 \else
528 \advance\@tempcnta\@ne
529 \expandafter\lst@GFM@
530 \fi}
\lst@gtempboxa
531\newbox\lst@gtempboxa
532h/kerneli
14 Doing output
14.1 Basic registers and keys
533h∗kerneli
The current character string is kept in a token register and a counter holds its length. Here we define the macros to put characters into the output queue.
\lst@token
\lst@length
are allocated here. Quite a useful comment, isn’t it?
534\newtoks\lst@token \newcount\lst@length
\lst@ResetToken
\lst@lastother
The two registers get empty respectively zero at the beginning of each line. After receiving a report from Claus Atzenbeck—I removed such a bug many times—I decided to reset these registers in theEndGrouphook, too.
535\def\lst@ResetToken{\lst@token{}\lst@length\z@}
536\lst@AddToHook{InitVarsBOL}{\lst@ResetToken \let\lst@lastother\@empty}
537\lst@AddToHook{EndGroup}{\lst@ResetToken \let\lst@lastother\@empty}
The macro\lst@lastotherwill be equivalent to the last ‘other’ character, which leads us to\lst@ifletter.
\lst@ifletter indicates whether the token contains an identifier or other characters.
538\def\lst@lettertrue{\let\lst@ifletter\iftrue}
539\def\lst@letterfalse{\let\lst@ifletter\iffalse}
540\lst@AddToHook{InitVars}{\lst@letterfalse}
\lst@Append puts the argument into the output queue.
541\def\lst@Append#1{\advance\lst@length\@ne
542 \lst@token=\expandafter{\the\lst@token#1}}
\lst@AppendOther Depending on the current state, we first output the character string as an identifier.
Then we save the ‘argument’ via\futureletand call the macro\lst@Appendto do the rest.
543\def\lst@AppendOther{%
544 \lst@ifletter \lst@Output\lst@letterfalse \fi
545 \futurelet\lst@lastother\lst@Append}
\lst@AppendLetter We output a non-identifier string if necessary and call\lst@Append.
546\def\lst@AppendLetter{%
547 \lst@ifletter\else \lst@OutputOther\lst@lettertrue \fi
548 \lst@Append}
\lst@SaveToken
\lst@RestoreToken
If a group end appears and ruins the character string, we can use these macros to save and restore the contents. \lst@thestyleis the current printing style and must be saved and restored, too.
549\def\lst@SaveToken{%
550 \global\let\lst@gthestyle\lst@thestyle
551 \global\let\lst@glastother\lst@lastother
552 \xdef\lst@RestoreToken{\noexpand\lst@token{\the\lst@token}%
553 \noexpand\lst@length\the\lst@length\relax
554 \noexpand\let\noexpand\lst@thestyle
555 \noexpand\lst@gthestyle
556 \noexpand\let\noexpand\lst@lastother
557 \noexpand\lst@glastother}}
Now – that means after a bug report by Rolf Niepraschk – \lst@lastother is also saved and restored.
\lst@IfLastOtherOneOf Finally, this obvious implementation.
558\def\lst@IfLastOtherOneOf#1{\lst@IfLastOtherOneOf@ #1\relax}
559\def\lst@IfLastOtherOneOf@#1{%
560 \ifx #1\relax
561 \expandafter\@secondoftwo
562 \else
563 \ifx\lst@lastother#1%
564 \lst@IfLastOtherOneOf@t
565 \else
566 \expandafter\expandafter\expandafter\lst@IfLastOtherOneOf@
567 \fi
568 \fi}
569\def\lst@IfLastOtherOneOf@t#1\fi\fi#2\relax{\fi\fi\@firstoftwo}
The current position is either the dimension\lst@currlwidth, which is the horizontal position without taking the current character string into account, or it’s the current column starting with number 0. This is\lst@column−\lst@pos+
\lst@length. Moreover we have\lst@lostspacewhich is the difference between the current and the desired line width. We define macros to insert this lost space.
\lst@currlwidth
\lst@column
\lst@pos
the current line width and two counters.
570\newdimen\lst@currlwidth % \global
571\newcount\lst@column \newcount\lst@pos % \global
572\lst@AddToHook{InitVarsBOL}
573 {\global\lst@currlwidth\z@ \global\lst@pos\z@ \global\lst@column\z@}
\lst@CalcColumn sets\@tempcnta to the current column. Note that\lst@poswill be nonpositive.
574\def\lst@CalcColumn{%
575 \@tempcnta\lst@column
576 \advance\@tempcnta\lst@length
577 \advance\@tempcnta-\lst@pos}
\lst@lostspace Whenever this dimension is positive we can insert space. A negative ‘lost space’
means that the printed line is wider than expected.
578\newdimen\lst@lostspace % \global
579\lst@AddToHook{InitVarsBOL}{\global\lst@lostspace\z@}
\lst@UseLostSpace We insert space and reset it if and only if\lst@lostspaceis positive.
580\def\lst@UseLostSpace{\ifdim\lst@lostspace>\z@ \lst@InsertLostSpace \fi}
\lst@InsertLostSpace
\lst@InsertHalfLostSpace
Ditto, but insert even if negative. \lst@Kernwill be defined very soon.
581\def\lst@InsertLostSpace{%
582 \lst@Kern\lst@lostspace \global\lst@lostspace\z@}
583\def\lst@InsertHalfLostSpace{%
584 \global\lst@lostspace.5\lst@lostspace \lst@Kern\lst@lostspace}
Column widths Here we deal with the width of a single column, which equals the width of a single character box. Keep in mind that there are fixed and flexible column formats.
\lst@width basewidth
basewidthassigns the values to macros and tests whether they are negative.
585\newdimen\lst@width
586\lst@Key{basewidth}{0.6em,0.45em}{\lstKV@CSTwoArg{#1}%
587 {\def\lst@widthfixed{##1}\def\lst@widthflexible{##2}%
588 \ifx\lst@widthflexible\@empty
589 \let\lst@widthflexible\lst@widthfixed
590 \fi
591 \def\lst@temp{\PackageError{Listings}%
592 {Negative value(s) treated as zero}%
593 \@ehc}%
594 \let\lst@error\@empty
595 \ifdim \lst@widthfixed<\z@
596 \let\lst@error\lst@temp \let\lst@widthfixed\z@
597 \fi
598 \ifdim \lst@widthflexible<\z@
599 \let\lst@error\lst@temp \let\lst@widthflexible\z@
600 \fi
601 \lst@error}}
We set the dimension in a special hook.
602\lst@AddToHook{FontAdjust}
603 {\lst@width=\lst@ifflexible\lst@widthflexible
604 \else\lst@widthfixed\fi \relax}
fontadjust
\lst@FontAdjust
This hook is controlled by a switch and is always executed at InitVars.
605\lst@Key{fontadjust}{false}[t]{\lstKV@SetIf{#1}\lst@iffontadjust}
606\def\lst@FontAdjust{\lst@iffontadjust \lsthk@FontAdjust \fi}
607\lst@AddToHook{InitVars}{\lsthk@FontAdjust}