• Tidak ada hasil yang ditemukan

Diverse helpers

Dalam dokumen The Listings Package (Halaman 103-106)

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

Dalam dokumen The Listings Package (Halaman 103-106)