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}