diff options
Diffstat (limited to 'Master/texmf-dist/tex/optex/base/makeindex.opm')
-rw-r--r-- | Master/texmf-dist/tex/optex/base/makeindex.opm | 214 |
1 files changed, 158 insertions, 56 deletions
diff --git a/Master/texmf-dist/tex/optex/base/makeindex.opm b/Master/texmf-dist/tex/optex/base/makeindex.opm index e0e7d7ad6cc..ba503525591 100644 --- a/Master/texmf-dist/tex/optex/base/makeindex.opm +++ b/Master/texmf-dist/tex/optex/base/makeindex.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \makeindex {Makeindex and sorting <2022-03-18>} % preloaded in format +\_codedecl \makeindex {Makeindex and sorting <2022-06-28>} % preloaded in format \_doc ----------------------------- \^`\makeindex` implements sorting algorithm at \TeX/ macro-language level. @@ -16,95 +16,163 @@ before acute before circumflex before ring. At less priority: lowercase letters must be before uppercase letters. - The \`\_sortingdata``<lang-tag>` implements these rules for the language - given by <lang-tag>. The <lang-tag> is typicaly ISO 639-1 code of the language - and it is declared by \~`\_preplang` defined in section~\ref[langdecl]. - The \`\_sortingdatacs` for Czech rules is defined below. + The \`\_sortingdatalatin` + implements these rules for the languages with latin alphabets. The groups between commas are not distinguished in the first pass. The second pass distinguishes all characters mentioned in the - `\_sortingdata<lang-tag>` (commas are ignored). The order of letters - in the `\_sortingdata<lang-tag>` macro is significant for the sorting algorithm. + \^`\_sortingdatalatin` (commas are ignored). The order of letters + in the \^`\_sortingdatalatin` macro is significant for the sorting algorithm. \_cod ----------------------------- -\_def \_sortingdatacs {% +\_def \_sortingdatalatin {% /,{ },-,&,@,% - aAäÄáÁ,% + aAàÀâÂäÄáÁ,% + ąĄ,% bB,% cC,% - čČ,% + ćĆčČ,% dDďĎ,% - eEéÉěĚ,% + eEèÈéÉëËêÊěĚ,% + ęĘ,% fF,% gG,% hH,% ^^T^^U^^V,% ch Ch CH - iIíÍ,% + iIíÍïÏîÎ,% jJ,% kK,% lLĺĹľĽ,% + łŁ,% mM,% nNňŇ,% + ńŃñÑ,% oOöÖóÓôÔ,% pP,% qQ,% rRŕŔ,% řŘ,% - sS,% - šŠ,% + sSß,% + śŚšŠ,% tTťŤ,% - uUüÜúÚůŮ,% + uUùÙûÛüÜúÚůŮűŰ,% vV,% wW,% xX,% - yYýÝ,% + yYýÝÿŸ,% zZ,% žŽ,% + źŹ,% + żŻ,% + ^^Z,% Hungarian: cz:c^^Z, etc., see \_compoundcharshu in lang-data.opm 0,1,2,3,4,5,6,7,8,9,'% } \_doc ----------------------------- - Characters to be ignored are declared in \`\_ignoredchars``<lang-tag>`. - See \`\_ignoredcharscs` for Czech rules. These characters are ignored in the first pass + Characters to be ignored during sorting are declared in \`\_ignoredcharsgeneric`. + These characters are ignored in the first pass without additional condition. All characters are taken into account in the second pass: ASCII characters with code $\string<65$ are sorted first if they - are not mentioned in the \^`\_sortingdata``<lang-tag>` macro. + are not mentioned in the `\_sortingdata...` macro. Others not mentioned characters have undefined behavior during sorting. + \_cod ----------------------------- + +\_def \_ignoredcharsgeneric {.,;?!:'"|()[]<>=+-} - The compound characters (two or more characters interpreted as one - character in the sorting algorithm) are mapped to single invisible characters - in \`\_compoundchars``<lang-tag>`, see \`\_compoundcharscs` below for Czech rules, - where ch or Ch or CH are declared as a single letter sorted between H and I. - See \^`\_sortingdatacs` above where these declared characters are used. + \_doc ----------------------------- + Sorting is always processed by rules of a given language. The macros + \`\_sortingdata``<lang-tag>`, \`\_ignoredchars``<lang-tag>` + and \`\_compoundchars``<lang-tag>` declare these rules. + The `<lang-tag>` is ISO code of the language: en, cs, de, pl, es for example. + The English language is implemented here. Other languages are implemented + in the `lang-data.opm` file (see section~\ref[langdata]). \_cod ----------------------------- -\_def \_ignoredcharscs {.,;?!:'"|()[]<>=+} -\_def \_compoundcharscs {ch:^^T Ch:^^U CH:^^V} % DZ etc. are sorted normally +\_let \_sortingdataen = \_sortingdatalatin % English alphabet is subset of Latin +\_let \_ignoredcharsen = \_ignoredcharsgeneric +\_def \_compoundcharsen {} % English doesn't have compound characters like DZ \_doc ----------------------------- + The \^`\_compoundchars``<lang-tag>` can declare changes performed before + sorting. For example Czech language declares: + \begtt + \_let \_sortingdatacs = \_sortingdatalatin % Czech alphabet is subset of Latin + \_def \_compoundcharscs {ch:^^T Ch:^^U CH:^^V} + \endtt + It transforms two-letters `ch` to single character `^^T` because ch is + treated as single compound character by Czech rules and CH is sorted between H and I. + See \^`\_sortingdatalatin` where `^^T` is used. This declaration makes more + transformations of Ch and CH too. The declarations of the form `x:y` in the + \^`\_compoundchars``<lang-tag>` are separated by space. + + You can declare a transformation from single letter to more letters too. For + example German rules sets ß equal to ss during sorting: + \begtt + \_let \_sortingdatade = \_sortingdatalatin % German alphabet is subset of Latin + \_def \_compoundcharsde {ß:ss} + \endtt + If there are two words equal after first pass of sorting: Masse (mass) + and Maße (measures) for example, then second pass must decide about the + order. DIN 5007, section 6.1 says: ss must be before ß in this case. So, + we want to switch off the \^`\_compoundchars` declaration for the second + pass and use the order of s and ß given in `\_sortingdata`. This is + possible if the \`\_xcompoundchars``<lang-tag>` is defined. + It has precedence in the second pass of sorting. We declare for German: + \begtt + \_def \_xcompoundcharsde {} + \endtt + Geman rules mention alternative sorting for phone-books or similar lists of + names. The letters ä ö ü should be interpreted as ae, oe and ue. So we get + Mueller $\lt$ Müller $\lt$ Muff. If this rule is not taken into account, we get + Mueller $\lt$ Muff $\lt$ Müller. The rule can be implemented by: + \begtt + \_def \_compoundcharsde {ß:ss Ä:AE Ö:OE Ü:UE ä:ae ö:oe ü:ue} + \endtt + Because u $\lt$ ü in `\_sortingdata` and because `\_xcompoundcharsde` is + empty, we have Mueller $\lt$ Müller after second pass of the sorting. + You can declare these macros for more languages if you wish to use `\makeindex` with sorting rules with respect to your language. Note: if you need to map compound characters to a character, don't use `^^I`, `^^J` or `^^M` because these characters have very specific category codes. - And use spaces to separate more mappings, like in \^`\_compoundcharscs` above. - If you create `\_sortingdata` etc. for your language, please, send them + If you created `\_sortingdata` etc. for your language, please, send them to me. I am ready to add them to the file `lang-data.opm` in a new \OpTeX/ release. - See also section~\ref[langdecl]. - - Preparing to primary pass is implemented by the \`\_setprimarysorting` macro. - It is called from `\makeindex` macro and all processing of sorting is in a group. + See also section~\ref[langdata]. + + French sorting rule says: if the words are the same except for accents + then accented letters are sorted after unaccented leters but + read the words from their end in the second pass. + For example corect sorting is: cote $\lt$ côte $\lt$ coté + $\lt$ côté. This rule can be activated if the contol sequence + \`\_secondpass``<lang-tag>` is set to \^`\_reversewords`. + For example, `lang-data.opm` declares `\_let\_secondpassfr=\_reversewords`. + + \bigskip + Preparing to primary pass is performed by the \`\_setprimarysorting` macro + implemented here. + The <lang-tag> is saved to the \^`\_sortinglang` macro when sorting is + initialized in \^`\_dosorting` (it is typicaly derived from current `\language` value). + The \^`\_setprimarysorting` is called from \^`\_dosorting` macro and all + processing of sorting is in a group. It sets actual + \^`\_sortingdata`, \^`\_compoundchars` and \^`\_ignoredchars` if given language + declares them. If not then warning will be printed using \`\_nold` macro + and English data are used. The `\lccode` of all characters from + \^`\_sortingdata` and \^`\_ignoredchars` are set. The sorted words will be converted + using \^`\_compoundchars` followed by `\lowercase` before first pass is run. \_cod ----------------------------- \_def\_setprimarysorting {% \_ea\_let \_ea\_sortingdata \_csname _sortingdata\_sortinglang\_endcsname \_ea\_let \_ea\_compoundchars \_csname _compoundchars\_sortinglang\_endcsname \_ea\_let \_ea\_ignoredchars \_csname _ignoredchars\_sortinglang\_endcsname + \_def\_nold{}% \_ifx \_sortingdata\_relax \_addto\_nold{ sortingdata}% \_let \_sortingdata = \_sortingdataen \_fi \_ifx \_compoundchars\_relax \_addto\_nold{ compoundchars}% \_let \_compoundchars = \_compoundcharsen \_fi \_ifx \_ignoredchars\_relax \_addto\_nold{ ignoredchars}% \_let \_ignoredchars = \_ignoredcharsen \_fi + \_ifx\_nold\_empty\_else \_opwarning{Missing\_nold\_space for language (\_sortinglang)}\_fi \_ifx \_compoundchars\_empty \_else \_edef \_compoundchars {\_detokenize\_ea{\_compoundchars} }\_fi % all must be catcode 12 \_def \_act ##1{\_ifx##1\_relax \_else @@ -135,12 +203,11 @@ The \`\_preparesorting` `\,<string>` converts `<string>` to `\_tmpb` with respect to the data initialized in \^`\_setprimarysorting` or \^`\_setsecondarysorting`.\nl - The compoud characters are converted to single characters by the - \`\_docompound` macro. + The compoud characters are converted by the \`\_docompound` macro. \_cod ----------------------------- \_def \_preparesorting #1{% - \_edef \_tmpb {\_ea\_ignorefirst\_csstring #1}% \,<string> -> <string> + \_edef \_tmpb {\_ea\_ignoreit\_csstring #1}% \,<string> -> <string> \_ea \_docompound \_compoundchars \_relax:{} % replace compound characters \_lowercase \_ea{\_ea\_def \_ea\_tmpb \_ea{\_tmpb}}% convert in respect to \_sortingdata \_ea\_replstring \_ea\_tmpb \_ea{\_csstring\^^I}{}% remove ignored characters @@ -148,7 +215,6 @@ \_def \_docompound #1:#2 {% \_ifx\_relax#1\_else \_replstring\_tmpb {#1}{#2}\_ea\_docompound \_fi } -\_def \_ignorefirst#1{} \_doc ----------------------------- Macro \`\_isAleB` `\,<string1> \,<string2>` returns the result of comparison @@ -160,7 +226,7 @@ comparison. \nl The macro - \`\_testAleB` `<converted string1>&\_relax<converted-string2>\_relax \,<string1>\,<string2>`\nl + \`\_testAleB` `<converted-string1>&\_relax<converted-string2>&\_relax \,<string1>\,<string2>`\nl does the real work. It reads the first character from both converted strings, compares them and if it is equal then calls itself recursively else gives the result. \_cod ----------------------------- @@ -178,17 +244,27 @@ \_else \_ifnum `#1<`#3 \_AleBtrue \_else \_AleBfalse \_fi \_fi } + + \_doc ----------------------------- + The \`\_testAleBsecondary` `\,<string1> \,<string2>` is run if the + words are equal in the primary pass. It runs \^`\_setsecondarysorting` if it + was not initialized already. Then prepares compared words to `\_tmpa` and + `\_tmpb` and corrects them by \^`\_prepsecondpass` if needed. + Finaly, the test is recursively done by the macro \`\_testAleBsecondaryX` + `<converted-string1>0\_relax<converted-string2>1\_relax` + \_cod ----------------------------- + + \_def\_testAleBsecondary#1#2{% - \_bgroup - \_setsecondarysorting - \_preparesorting#1\_let\_tmpa=\_tmpb \_preparesorting#2% - \_edef\_tmpb{\_tmpa0\_relax\_tmpb1\_relax}% - \_ea\_testAleBsecondaryX \_tmpb - \_egroup + \_setsecondarysorting \_let\_setsecondarysorting=\_relax + \_preparesorting#1\_let\_tmpa=\_tmpb \_preparesorting#2% + \_prepsecondpass + \_edef\_tmpb{\_tmpa0\_relax\_tmpb1\_relax}% + \_ea\_testAleBsecondaryX \_tmpb } \_def\_testAleBsecondaryX #1#2\_relax #3#4\_relax {% \_if #1#3\_testAleBsecondaryX #2\_relax #4\_relax - \_else \_ifnum `#1<`#3 \_global\_AleBtrue \_else \_global \_AleBfalse \_fi + \_else \_ifnum `#1<`#3 \_AleBtrue \_else \_AleBfalse \_fi \_fi } @@ -197,7 +273,7 @@ code is created by my son Miroslav. The \`\_mergesort` macro expects that all items in `\_iilist` are separated by a comma when it starts. It ends with sorted items in `\_iilist` without commas. - So `\_dosorting` macro must prepare commas between items. + So \^`\_dosorting` macro must prepare commas between items. \_cod ----------------------------- \_def\_mergesort #1#2,#3{% by Miroslav Olsak @@ -249,30 +325,53 @@ \_newifi \_ifasciisorting \_asciisortingfalse \_def\_dosorting #1{% \_begingroup - \_def\_nold{}% - \_ifx\_sotringlang\_undefined \_edef\_sortinglang{\_cs{_lan:\_the\_language}}\_fi - \_ifasciisorting - \_edef\_sortinglang{ASCII}% - \_def \_preparesorting##1{\_edef\_tmpb{\_ea\_ignorefirst\_csstring##1}}% + \_ifasciisorting \_def\_sortinglang{ASCII}\_fi + \_ifx\_sortinglang\_undefined \_edef\_sortinglang{\_cs{_lan:\_the\_language}}\_fi + \_message{OpTeX: Sorting \_string#1 (\_sortinglang) ...^^J}% + \_ismacro\_sortinglang{ASCII}\_iftrue + \_def \_preparesorting##1{\_edef\_tmpb{\_ea\_ignoreit\_csstring##1}}% \_let \_setsecondarysorting=\_relax \_else \_setprimarysorting \_fi - \_message{OpTeX: Sorting \_string#1 (\_sortinglang) ...^^J}% - \_ifx\_nold\_empty\_else \_opwarning{Missing\_nold\_space for language (\_sortinglang)}\_fi \_def \_act##1{\_preparesorting ##1\_edef##1{\_tmpb}}% - \_ea\_xargs \_ea\_act #1;% + \_ea\_xargs \_ea\_act #1;% \_preparesorting for first pass of sorting applied + \_ifcsname _xcompoundchars\_sortinglang\_endcsname + \_ea\_let \_ea\_compoundchars \_csname _xcompoundchars\_sortinglang\_endcsname + \_fi % \_compoundchars can differ in the second pass of sorting + \_csname _secondpass\_sortinglang \_endcsname % activates \_reversewords if needed \_def \_act##1{\_addto #1{##1,}}% - \_edef #1{\_ea}\_ea\_xargs \_ea\_act #1;% + \_edef #1{\_ea}\_ea\_xargs \_ea\_act #1;% commas between items added, mergesort initialized \_edef \_iilist{\_ea}\_ea\_mergesort #1\_end,\_end \_ea\_endgroup \_ea\_def\_ea#1\_ea{\_iilist}% } \_doc ----------------------------- + French rules needs reverese reading the words in the second pass. + The \`\_reversewords` is activated in this case and it adds + new job to the macro \`\_prepsecondpass`: it reverses the letters in + the compared words (saved in `\_tmpa` and `\_tmpb`) by the expandable + \`\_sortrevers` macro. The \^`\_prepsecondpass` macro is used in the + \^`\_testAleBsecondary` and it is empty by default. + \_cod ----------------------------- + +\_def\_prepsecondpass{} +\_def\_reversewords{% + \_addto\_prepsecondpass{\_edef\_tmpa{\_ea\_sortrevers\_tmpa\_relax}% + \_edef\_tmpb{\_ea\_sortrevers\_tmpb\_relax}}% +} +\_def\_sortrevers #1#2\_relax{\_ifx^#2^#1\_else \_sortrevers#2\_relax #1\_fi} + + \_doc ----------------------------- The \`\makeindex` prints the index. First, it sorts the `\_iilist` second, it prints the sorted `\_iilist`, each item is printed - using \^`\_printindexitem`. + using \^`\_printindexitem`.\nl + We set `\leftskip=\iindent` and we suppose that each index entry + starts by `\noindent\hskip-\iindent` (see the macro \~`\_printii`). + Then the next lines of the same index + entry (if the page list is broken to more pages) is indented by + `\leftskip=\iindent`. \_cod ----------------------------- \_def\_makeindex{\_par @@ -300,7 +399,7 @@ \_ifcsname _\_csstring #1\_endcsname \_ea\_ea\_ea \_printii \_csname _\_csstring #1\_endcsname &% \_else - \_ea\_ea\_ea\_printii \_ea\_ignorefirst \_csstring #1&% + \_ea\_ea\_ea\_printii \_ea\_ignoreit \_csstring #1&% \_fi \_ea\_printiipages #1& } @@ -450,6 +549,9 @@ \_endcode % ------------------------------------- +2022-06-28 \_reversewords for French sorting introduced +2022-06-28 \_sortingdatalatin covers more languages +2022-06-28 \_xcompoundchars introduced, comments upgraded (German sorting mentioned) 2022-03-18 \iid didn't ignore space, bug fixed 2022-02-19 \_sotringdataen etc. moved to lang-data.opm file 2021-02-15 \_expandafter -> \_ea |