• Tidak ada hasil yang ditemukan

Escaping to L A TEX

Dalam dokumen The Listings Package (Halaman 141-147)

We now define the . . . damned . . . the aspect has escaped!

1710h∗misci

1711\lst@BeginAspect{escape}

texcl Communication with J¨orn Wilms is responsible for this key. The definition and the first hooks are easy.

1712\lst@Key{texcl}{false}[t]{\lstKV@SetIf{#1}\lst@iftexcl}

1713\lst@AddToHook{TextStyle}{\let\lst@iftexcl\iffalse}

1714\lst@AddToHook{EOL}

1715 {\ifnum\lst@mode=\lst@TeXLmode

1716 \expandafter\lst@escapeend

1717 \expandafter\lst@LeaveAllModes

1718 \expandafter\lst@ReenterModes

1719 \fi}

If the user wants TEX comment lines, we print the comment separator and inter- rupt the normal processing.

1720\lst@AddToHook{AfterBeginComment}

1721 {\lst@iftexcl \lst@ifLmode \lst@ifdropinput\else

1722 \lst@PrintToken

1723 \lst@LeaveMode \lst@InterruptModes

1724 \lst@EnterMode{\lst@TeXLmode}{\lst@modetrue\lst@commentstyle}%

1725 \expandafter\expandafter\expandafter\lst@escapebegin

1726 \fi \fi \fi}

1727\lst@NewMode\lst@TeXLmode

\lst@ActiveCDefX Same as\lst@CDefX but we both make#1active and assign a new catcode.

1728\gdef\lst@ActiveCDefX#1{\lst@ActiveCDefX@#1}

1729\gdef\lst@ActiveCDefX@#1#2#3{

1730 \catcode‘#1\active\lccode‘\~=‘#1%

1731 \lowercase{\lst@CDefIt~}{#2}{#3}{}}

\lst@Escape gets four arguments all in all. The first and second are the ‘begin’ and ‘end’

escape sequences, the third is executed when the escape starts, and the fourth right before ending it. We use the same mechanism as for TEX comment lines.

The\lst@ifdropinputtest has been added after a bug report by Michael Weber.

The\lst@newlines\z@was added due to a bug report by Frank Atanassow.

1732\gdef\lst@Escape#1#2#3#4{%

1733 \lst@CArgX #1\relax\lst@CDefX

1734 {}%

1735 {\lst@ifdropinput\else

1736 \lst@TrackNewLines\lst@OutputLostSpace \lst@XPrintToken

1737 \lst@InterruptModes

1738 \lst@EnterMode{\lst@TeXmode}{\lst@modetrue}%

Now we must define the character sequence to end the escape.

1739 \ifx\^^M#2%

1740 \lst@CArg #2\relax\lst@ActiveCDefX

1741 {}%

1742 {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes}%

1743 {\lst@MProcessListing}%

1744 \else

1745 \lst@CArg #2\relax\lst@ActiveCDefX

1746 {}%

1747 {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes

1748 \lst@newlines\z@ \lst@whitespacefalse}%

1749 {}%

1750 \fi

1751 #3\lst@escapebegin

1752 \fi}%

1753 {}}

The \lst@whitespacefalse above was added after a bug report from Martin Steffen.

1754\lst@NewMode\lst@TeXmode escapebegin

escapeend

The keys simply store the arguments.

1755\lst@Key{escapebegin}{}{\def\lst@escapebegin{#1}}

1756\lst@Key{escapeend}{}{\def\lst@escapeend{#1}}

escapechar The introduction of this key is due to a communication with Rui Oliveira. We define\lst@DefEsc and execute it after selecting the standard character table.

1757\lst@Key{escapechar}{}

1758 {\ifx\@empty#1\@empty

1759 \let\lst@DefEsc\relax

1760 \else

1761 \def\lst@DefEsc{\lst@Escape{#1}{#1}{}{}}%

1762 \fi}

1763\lst@AddToHook{TextStyle}{\let\lst@DefEsc\@empty}

1764\lst@AddToHook{SelectCharTable}{\lst@DefEsc}

escapeinside Nearly the same.

1765\lst@Key{escapeinside}{}{\lstKV@TwoArg{#1}%

1766 {\let\lst@DefEsc\@empty

1767 \ifx\@empty##1@empty\else \ifx\@empty##2\@empty\else

1768 \def\lst@DefEsc{\lst@Escape{##1}{##2}{}{}}%

1769 \fi\fi}}

mathescape This is a switch and checked after character table selection. We use\lst@Escape with math shifts as arguments, but all inside\hboxto determine the correct width.

1770\lst@Key{mathescape}{false}[t]{\lstKV@SetIf{#1}\lst@ifmathescape}

1771\lst@AddToHook{SelectCharTable}

1772 {\lst@ifmathescape \lst@Escape{\$}{\$}%

1773 {\setbox\@tempboxa=\hbox\bgroup$}%

1774 {$\egroup \lst@CalcLostSpaceAndOutput}\fi}

1775\lst@EndAspect

1776h/misci

16 Keywords

16.1 Making tests

We begin a new and very important aspect. First of all we need to initialize some variables in order to work around a bug reported by Beat Birkhofer.

1777h∗misci

1778\lst@BeginAspect{keywords}

1779\global\let\lst@ifsensitive\iftrue % init

1780\global\let\lst@ifsensitivedefed\iffalse % init % \global All keyword tests take the following three arguments.

#1 = hprefixi

#2 = \lst@hnamei@list(a list of macros which contain the keywords)

#3 = \lst@ghnamei@sty(global style macro) We begin with non memory-saving tests.

1781\lst@ifsavemem\else

\lst@KeywordTest Fast keyword tests take advance of the \lst@UMconstruction in section 15.3. If

\lst@UM is empty, all ‘use macro’ characters expand to their original characters.

Since\lsthprefixi@hkeywordiwill be equivalent to the appropriate style, we only

need to build the control sequence \lsthprefixi@hcurrent tokeniand assign it to

\lst@thestyle.

1782\gdef\lst@KeywordTest#1#2#3{%

1783 \begingroup \let\lst@UM\@empty

1784 \global\expandafter\let\expandafter\@gtempa

1785 \csname\@lst#1@\the\lst@token\endcsname

1786 \endgroup

1787 \ifx\@gtempa\relax\else

1788 \let\lst@thestyle\@gtempa

1789 \fi}

Note that we need neither#2nor#3here.

\lst@KEYWORDTEST Case insensitive tests make the current character string upper case and give it to a submacro similar to\lst@KeywordTest.

1790\gdef\lst@KEYWORDTEST{%

1791 \uppercase\expandafter{\expandafter

1792 \lst@KEYWORDTEST@\the\lst@token}\relax}

1793\gdef\lst@KEYWORDTEST@#1\relax#2#3#4{%

1794 \begingroup \let\lst@UM\@empty

1795 \global\expandafter\let\expandafter\@gtempa

1796 \csname\@lst#2@#1\endcsname

1797 \endgroup

1798 \ifx\@gtempa\relax\else

1799 \let\lst@thestyle\@gtempa

1800 \fi}

\lst@WorkingTest

\lst@WORKINGTEST

The same except that\lsthprefixi@hcurrent tokenimight be a working procedure;

it is executed.

1801\gdef\lst@WorkingTest#1#2#3{%

1802 \begingroup \let\lst@UM\@empty

1803 \global\expandafter\let\expandafter\@gtempa

1804 \csname\@lst#1@\the\lst@token\endcsname

1805 \endgroup

1806 \@gtempa}

1807\gdef\lst@WORKINGTEST{%

1808 \uppercase\expandafter{\expandafter

1809 \lst@WORKINGTEST@\the\lst@token}\relax}

1810\gdef\lst@WORKINGTEST@#1\relax#2#3#4{%

1811 \begingroup \let\lst@UM\@empty

1812 \global\expandafter\let\expandafter\@gtempa

1813 \csname\@lst#2@#1\endcsname

1814 \endgroup

1815 \@gtempa}

\lst@DefineKeywords Eventually we need macros which define and undefine \lsthprefixi@hkeywordi.

Here the arguments are

#1 = hprefixi

#2 = \lst@hnamei(a keyword list)

#3 = \lst@ghnamei@sty

We make the keywords upper case if necessary, . . .

1816\gdef\lst@DefineKeywords#1#2#3{%

1817 \lst@ifsensitive

1818 \def\lst@next{\lst@for#2}%

1819 \else

1820 \def\lst@next{\uppercase\expandafter{\expandafter\lst@for#2}}%

1821 \fi

1822 \lst@next\do

. . . iterate through the list, and make\lsthprefixi@hkeywordi(if undefined) equiv- alent to\lst@ghnamei@sty which is possibly a working macro.

1823 {\expandafter\ifx\csname\@lst#1@##1\endcsname\relax

1824 \global\expandafter\let\csname\@lst#1@##1\endcsname#3%

1825 \fi}}

\lst@UndefineKeywords We make the keywords upper case if necessary, . . .

1826\gdef\lst@UndefineKeywords#1#2#3{%

1827 \lst@ifsensitivedefed

1828 \def\lst@next{\lst@for#2}%

1829 \else

1830 \def\lst@next{\uppercase\expandafter{\expandafter\lst@for#2}}%

1831 \fi

1832 \lst@next\do

. . . iterate through the list, and ‘undefine’\lsthprefixi@hkeywordiif it’s equivalent to\lst@ghnamei@sty.

1833 {\expandafter\ifx\csname\@lst#1@##1\endcsname#3%

1834 \global\expandafter\let\csname\@lst#1@##1\endcsname\relax

1835 \fi}}

Thanks to Magnus Lewis-Smith a wrong #2 in the replacement text could be changed to#3.

And now memory-saving tests.

1836\fi

1837\lst@ifsavemem

\lst@IfOneOutOf The definition here is similar to \lst@IfOneOf, but its second argument is a

\lst@hnamei@list. Therefore we test a list of macros here.

1838\gdef\lst@IfOneOutOf#1\relax#2{%

1839 \def\lst@temp##1,#1,##2##3\relax{%

1840 \ifx\@empty##2\else \expandafter\lst@IOOOfirst \fi}%

1841 \def\lst@next{\lst@IfOneOutOf@#1\relax}%

1842 \expandafter\lst@next#2\relax\relax}

We either execute thehelseipart or make the next test.

1843\gdef\lst@IfOneOutOf@#1\relax#2#3{%

1844 \ifx#2\relax

1845 \expandafter\@secondoftwo

1846 \else

1847 \expandafter\lst@temp\expandafter,#2,#1,\@empty\relax

1848 \expandafter\lst@next

1849 \fi}

1850\ifx\iffalse\else\fi

1851\gdef\lst@IOOOfirst#1\relax#2#3{\fi#2}

The line\ifx\iffalse\else\fibalances the\fiinside\lst@IOOOfirst.

\lst@IFONEOUTOF As in\lst@IFONEOFwe need two\uppercases here.

1852\gdef\lst@IFONEOUTOF#1\relax#2{%

1853 \uppercase{\def\lst@temp##1,#1},##2##3\relax{%

1854 \ifx\@empty##2\else \expandafter\lst@IOOOfirst \fi}%

1855 \def\lst@next{\lst@IFONEOUTOF@#1\relax}%

1856 \expandafter\lst@next#2\relax}

1857\gdef\lst@IFONEOUTOF@#1\relax#2#3{%

1858 \ifx#2\relax

1859 \expandafter\@secondoftwo

1860 \else

1861 \uppercase

1862 {\expandafter\lst@temp\expandafter,#2,#1,\@empty\relax}%

1863 \expandafter\lst@next

1864 \fi}

Note: The third last line uses the fact that keyword lists (not the list of keyword lists) are already made upper case if keywords are insensitive.

\lst@KWTest is a helper for the keyword and working identifier tests. We expand the token and call \lst@IfOneOf. The tests below will append appropriate htheni and helsei arguments.

1865\gdef\lst@KWTest{%

1866 \begingroup \let\lst@UM\@empty

1867 \expandafter\xdef\expandafter\@gtempa\expandafter{\the\lst@token}%

1868 \endgroup

1869 \expandafter\lst@IfOneOutOf\@gtempa\relax}

\lst@KeywordTest

\lst@KEYWORDTEST

are fairly easy now. Note that we don’t need#1=hprefixihere.

1870\gdef\lst@KeywordTest#1#2#3{\lst@KWTest #2{\let\lst@thestyle#3}{}}

1871\global\let\lst@KEYWORDTEST\lst@KeywordTest

For case insensitive tests we assign the insensitive version to \lst@IfOneOutOf.

Thus we need no extra definition here.

\lst@WorkingTest

\lst@WORKINGTEST

Ditto.

1872\gdef\lst@WorkingTest#1#2#3{\lst@KWTest #2#3{}}

1873\global\let\lst@WORKINGTEST\lst@WorkingTest

1874\fi

sensitive is a switch, presettrueevery language selection.

1875\lst@Key{sensitive}\relax[t]{\lstKV@SetIf{#1}\lst@ifsensitive}

1876\lst@AddToHook{SetLanguage}{\let\lst@ifsensitive\iftrue}

We select case insensitive definitions if necessary.

1877\lst@AddToHook{Init}

1878 {\lst@ifsensitive\else

1879 \let\lst@KeywordTest\lst@KEYWORDTEST

1880 \let\lst@WorkingTest\lst@WORKINGTEST

1881 \let\lst@IfOneOutOf\lst@IFONEOUTOF

1882 \fi}

\lst@MakeMacroUppercase makes the contents of#1(if defined) upper case.

1883\gdef\lst@MakeMacroUppercase#1{%

1884 \ifx\@undefined#1\else \uppercase\expandafter

1885 {\expandafter\def\expandafter#1\expandafter{#1}}%

1886 \fi}

Dalam dokumen The Listings Package (Halaman 141-147)