classoffset just stores the argument in a macro.
1966\lst@Key{classoffset}\z@{\def\lst@classoffset{#1}}
\lst@InstallFamily Recall the parameters
#1 = hprefixi
#2 = hnamei
#3 = hstyle namei
#4 = hstyle initi
#5 = hdefault style namei
#6 = hworking procedurei
#7 = l|o(language or other key)
#8 = d|o(DetectKeywordsor Outputhook)
First we define the keys and the style keyhstyle nameiif and only if the name is not empty.
1967\gdef\lst@InstallFamily#1#2#3#4#5{%
1968 \lst@Key{#2}\relax{\lst@UseFamily{#2}##1\relax\lst@MakeKeywords}%
1969 \lst@Key{more#2}\relax
1970 {\lst@UseFamily{#2}##1\relax\lst@MakeMoreKeywords}%
1971 \lst@Key{delete#2}\relax
1972 {\lst@UseFamily{#2}##1\relax\lst@DeleteKeywords}%
1973 \ifx\@empty#3\@empty\else
1974 \lst@Key{#3}{#4}{\lstKV@OptArg[\@ne]{##1}%
1975 {\@tempcnta\lst@classoffset \advance\@tempcnta####1\relax
1976 \@namedef{lst@#3\ifnum\@tempcnta=\@ne\else \the\@tempcnta
1977 \fi}{####2}}}%
1978 \fi
1979 \expandafter\lst@InstallFamily@
1980 \csname\@lst @#2@data\expandafter\endcsname
1981 \csname\@lst @#5\endcsname {#1}{#2}{#3}}
Now we check whetherhworking procedureiis empty. Accordingly we use working procedure orstyle in the ‘data’ definition. The working procedure is defined right here if necessary.
1982\gdef\lst@InstallFamily@#1#2#3#4#5#6#7#8{%
1983 \gdef#1{{#3}{#4}{#5}#2#7}%
1984 \long\def\lst@temp##1{#6}%
1985 \ifx\lst@temp\@gobble
1986 \lst@AddTo#1{s#8}%
1987 \else
1988 \lst@AddTo#1{w#8}%
1989 \global\@namedef{lst@g#4@wp}##1{#6}%
1990 \fi}
Nothing else is defined here, all the rest is done on demand.
\lst@UseFamily We look for the optional class number, provide this member, . . .
1991\gdef\lst@UseFamily#1{%
1992 \def\lst@family{#1}%
1993 \@ifnextchar[\lst@UseFamily@{\lst@UseFamily@[\@ne]}}
1994\gdef\lst@UseFamily@[#1]{%
1995 \@tempcnta\lst@classoffset \advance\@tempcnta#1\relax
1996 \lst@ProvideFamily\lst@family . . . and build the control sequences . . .
1997 \lst@UseFamily@a
1998 {\lst@family\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}}
1999\gdef\lst@UseFamily@a#1{%
2000 \expandafter\lst@UseFamily@b
2001 \csname\@lst @#1@list\expandafter\endcsname
2002 \csname\@lst @#1\expandafter\endcsname
2003 \csname\@lst @#1@also\expandafter\endcsname
2004 \csname\@lst @g#1\endcsname}
. . . required for\lst@MakeKeywordsand #6.
2005\gdef\lst@UseFamily@b#1#2#3#4#5\relax#6{\lstKV@XOptArg[]{#5}#6#1#2#3#4}
\lst@ProvideFamily provides the member ‘\the\@tempcnta’ of the family #1. We do nothing if the member already exists. Otherwise we expand the data macro defined above.
Note that we don’t use the counter if it equals one. Since a bug report by Kris Luyten keyword families use the prefix lstfam instead oflst. The marker
\lstfam@#1[hnumberi]is defined globally since a bug report by Edsko de Vries.
2006\gdef\lst@ProvideFamily#1{%
2007 \@ifundefined{lstfam@#1\ifnum\@tempcnta=\@ne\else\the\@tempcnta\fi}%
2008 {\global\@namedef{lstfam@#1\ifnum\@tempcnta=\@ne\else
2009 \the\@tempcnta\fi}{}%
2010 \expandafter\expandafter\expandafter\lst@ProvideFamily@
2011 \csname\@lst @#1@data\endcsname
2012 {\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}}%
2013 {}}%
Now we have the following arguments
#1 = hprefixi
#2 = hnamei
#3 = hstyle namei
#4 = hdefault style namei
#5 = l|o(language or other key)
#6 = w|s(working procedure or style)
#7 = d|o(DetectKeywordsor Outputhook)
#8 = \ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi
We define \lst@ghnameihnumberi@sty to call either\lst@ghnamei@wpwith the number as argument or\lst@hstyle nameihnumberiwhere the number belongs to the control sequence.
2014\gdef\lst@ProvideFamily@#1#2#3#4#5#6#7#8{%
2015 \expandafter\xdef\csname\@lst @g#2#8@sty\endcsname
2016 {\if #6w%
2017 \expandafter\noexpand\csname\@lst @g#2@wp\endcsname{#8}%
2018 \else
2019 \expandafter\noexpand\csname\@lst @#3#8\endcsname
2020 \fi}%
We ensure the existence of the style macro. This is done in the Init hook by assigning the default style if necessary.
2021 \ifx\@empty#3\@empty\else
2022 \edef\lst@temp{\noexpand\lst@AddToHook{Init}{%
2023 \noexpand\lst@ProvideStyle\expandafter\noexpand
2024 \csname\@lst @#3#8\endcsname\noexpand#4}}%
2025 \lst@temp
2026 \fi
We call a submacro to do the rest. It requires some control sequences.
2027 \expandafter\lst@ProvideFamily@@
2028 \csname\@lst @#2#8@list\expandafter\endcsname
2029 \csname\@lst @#2#8\expandafter\endcsname
2030 \csname\@lst @#2#8@also\expandafter\endcsname
2031 \csname\@lst @g#2#8@list\expandafter\endcsname
2032 \csname\@lst @g#2#8\expandafter\endcsname
2033 \csname\@lst @g#2#8@sty\expandafter\endcsname
2034 {#1}#5#6#7}
Now we have (except thathnumberiis possibly always missing)
#1 = \lst@hnameihnumberi@list
#2 = \lst@hnameihnumberi
#3 = \lst@hnameihnumberi@also
#4 = \lst@ghnameihnumberi@list
#5 = \lst@ghnameihnumberi
#6 = \lst@ghnameihnumberi@sty
#7 = hprefixi
#8 = l|o(language or other key)
#9 = w|s(working procedure or style)
#10 = d|o(DetectKeywordsor Outputhook)
Note that#9and ‘#10’ are read by\lst@InstallTest. We initialize all required
‘variables’ (at SetLanguage) and install the test (which definition is in fact also delayed).
2035\gdef\lst@ProvideFamily@@#1#2#3#4#5#6#7#8{%
2036 \gdef#1{#2#5}\global\let#2\@empty \global\let#3\@empty % init
2037 \gdef#4{#2#5}\global\let#5\@empty % init
2038 \if #8l\relax
2039 \lst@AddToHook{SetLanguage}{\def#1{#2#5}\let#2\@empty}%
2040 \fi
2041 \lst@InstallTest{#7}#1#2#4#5#6}
\lst@InstallKeywords Now we take advance of the optional argument construction above. Thus, we just insert[\@ne]ashnumberiin the definitions of the keys.
2042\gdef\lst@InstallKeywords#1#2#3#4#5{%
2043 \lst@Key{#2}\relax
2044 {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeKeywords}%
2045 \lst@Key{more#2}\relax
2046 {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeMoreKeywords}%
2047 \lst@Key{delete#2}\relax
2048 {\lst@UseFamily{#2}[\@ne]##1\relax\lst@DeleteKeywords}%
2049 \ifx\@empty#3\@empty\else
2050 \lst@Key{#3}{#4}{\@namedef{lst@#3}{##1}}%
2051 \fi
2052 \expandafter\lst@InstallFamily@
2053 \csname\@lst @#2@data\expandafter\endcsname
2054 \csname\@lst @#5\endcsname {#1}{#2}{#3}}
\lst@ProvideStyle If the style macro#1is not defined, it becomes equivalent to#2.
2055\gdef\lst@ProvideStyle#1#2{%
2056 \ifx#1\@undefined \let#1#2%
2057 \else\ifx#1\relax \let#1#2\fi\fi}
Finally we define\lst@MakeKeywords, . . . ,\lst@DeleteKeywords. We begin with two helper.
\lst@BuildClassList After #1 follows a comma separated list of keyword classes terminated by ,\relax,, e.g. keywords2,emph1,\relax,. For each hitemi in this list we ap- pend the two macros\lst@hitemi\lst@ghitemito #1.
2058\gdef\lst@BuildClassList#1#2,{%
2059 \ifx\relax#2\@empty\else
2060 \ifx\@empty#2\@empty\else
2061 \lst@lExtend#1{\csname\@lst @#2\expandafter\endcsname
2062 \csname\@lst @g#2\endcsname}%
2063 \fi
2064 \expandafter\lst@BuildClassList\expandafter#1
2065 \fi}
\lst@DeleteClassesIn deletes pairs of tokens, namely the arguments#2#3to the submacro.
2066\gdef\lst@DeleteClassesIn#1#2{%
2067 \expandafter\lst@DCI@\expandafter#1#2\relax\relax}
2068\gdef\lst@DCI@#1#2#3{%
2069 \ifx#2\relax
2070 \expandafter\@gobbletwo
2071 \else
If we haven’t reached the end of the class list, we define a temporary macro which removes all appearances.
2072 \def\lst@temp##1#2#3##2{%
2073 \lst@lAddTo#1{##1}%
2074 \ifx ##2\relax\else
2075 \expandafter\lst@temp
2076 \fi ##2}%
2077 \let\@tempa#1\let#1\@empty
2078 \expandafter\lst@temp\@tempa#2#3\relax
2079 \fi
2080 \lst@DCI@#1}
\lst@MakeKeywords We empty some macros and make use of\lst@MakeMoreKeywords. Note that this and the next two definitions have the following arguments:
#1 = class list (in brackets)
#2 = keyword list
#3 = \lst@hnamei@list
#4 = \lst@hnamei
#5 = \lst@hnamei@also
#6 = \lst@ghnamei
2081\gdef\lst@MakeKeywords[#1]#2#3#4#5#6{%
2082 \def#3{#4#6}\let#4\@empty \let#5\@empty
2083 \lst@MakeMoreKeywords[#1]{#2}#3#4#5#6}
\lst@MakeMoreKeywords We append classes and keywords.
2084\gdef\lst@MakeMoreKeywords[#1]#2#3#4#5#6{%
2085 \lst@BuildClassList#3#1,\relax,%
2086 \lst@DefOther\lst@temp{,#2}\lst@lExtend#4\lst@temp}
\lst@DeleteKeywords We convert the keyword arguments via \lst@MakeKeywords and remove the classes and keywords.
2087\gdef\lst@DeleteKeywords[#1]#2#3#4#5#6{%
2088 \lst@MakeKeywords[#1]{#2}\@tempa\@tempb#5#6%
2089 \lst@DeleteClassesIn#3\@tempa
2090 \lst@DeleteKeysIn#4\@tempb}