%lexref 2015/01/11 v1.1 alpha %Copyright (c) Adrien Vion. adrien[dot]vion3[at]gmail[dot]com. %This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this license or any later version. %The latest version of this license is in http://www.latex-project.org/lppl.txt and version 1.3 or later is part of all distributions of LaTeX version 2005/12/01 or later. %------------ identification -------------- \ProvidesPackage{lexref}[2015/01/11 v1.1a]% \NeedsTeXFormat{LaTeX2e}% %------------ package loading -------------- \RequirePackage{etoolbox}% \RequirePackage{xargs}% \RequirePackage{xstring}% \RequirePackage{nomencl}% \RequirePackage{splitidx}% \RequirePackage{ifthen} \RequirePackage{stringstrings} %------------ initial code -------------- % Toggle creation \newtoggle{lexnoprint} \newtoggle{lexindexing} \newtoggle{lexnomencl} \newtoggle{lexpluralform} \newtoggle{lexaltoverride} \newtoggle{lexshortcutstolist} \newtoggle{lexrefCHfr} \newtoggle{lexrefCHde} \newtoggle{lexrefDE} \newcounter{lexcitecountinteger} % Error messages setting \newcommand{\lexcite@err@invalidthirdarg@DeclareLex}{\PackageError{lexref}{% Fourth argument of \protect\DeclareLex\space must be either 'alt' or nothing. Check your \protect\DeclareCite\space macros}} %------------ declaration of options -------------- \DeclareOption{noprint}{\toggletrue{lexnoprint}} \DeclareOption{indexing}{\toggletrue{lexindexing}\makeindex} \DeclareOption{nomencl}{\toggletrue{lexnomencl}\robustify{\nomenclature}\makenomenclature} \DeclareOption{shortcutstolist}{\toggletrue{lexshortcutstolist}\makenomenclature} \DeclareOption{CHfr}{\toggletrue{lexrefCHfr}} \DeclareOption{CHde}{\toggletrue{lexrefCHde}} \DeclareOption{DE}{\toggletrue{lexrefDE}} %------------ execution of options -------------- \ProcessOptions %------------ main code -------------- % DEFINITION OF LITERAL PREFIXES AND SHORTCUTS % % \NewLexShortcut % #1 = Shortcutname % #2 = Printed Shortcut % #3 (optional) = Unabreviated shortcut \newcommandx{\NewLexShortcut}[3][3]{% % 1) Creation of a toggle for nomenclature, if needed \iftoggle{lexshortcutstolist}{\newtoggle{#1nmcl}\global\togglefalse{#1nmcl}}{}% % 2) Creation of the Shortcut macro \expandafter\newcommandx\csname#1\endcsname{#2% % 3) Adding to nomenclature list, if needed \iftoggle{lexshortcutstolist}{% \ifstrempty{#3}{}{% \iftoggle{#1nmcl}% {}% {\nomenclature{#2}{#3}\global\toggletrue{#1nmcl}}% }}% {}% }% } % \RenewLexShortcut \newcommandx{\RenewLexShortcut}[3][3]{% % 1) Creation of the Shortcut macro \expandafter\renewcommandx\csname#1\endcsname{#2% % 2) Adding to nomenclature list, if needed \iftoggle{lexshortcutstolist}{% \ifstrempty{#3}{}{% \iftoggle{#1nmcl}% {}% {\nomenclature{#2}{#3}\global\toggletrue{#1nmcl}}% }}% {}% }% } % Default shortcuts: english \NewLexShortcut{DispPrefixMain}{art.}[article(s)]% \NewLexShortcut{DispsPrefixMain}{art.}% \NewLexShortcut{DispPrefixAlt}{\S}% \NewLexShortcut{DispsPrefixAlt}{\S\S}% \NewLexShortcut{SubPrefix}{par.}[paragraph(s)] \NewLexShortcut{SubSubPrefixNumber}{nr.}[number(s)] \NewLexShortcut{SubSubPrefixLetter}{let.}[letter(s)] \NewLexShortcut{sq}{sq.}[sequiturque] \NewLexShortcut{sqq}{sqq.}[sequunturque] \NewLexShortcut{analog}{by an.}[by analogy] % french shortcuts \iftoggle{lexrefCHfr}{% \RenewLexShortcut{DispPrefixMain}{art.}[article(s)]% \RenewLexShortcut{DispsPrefixMain}{art.}% \RenewLexShortcut{DispPrefixAlt}{\S}% \RenewLexShortcut{DispsPrefixAlt}{\S\S}% \RenewLexShortcut{SubPrefix}{al.}[alin\'ea(s)] \RenewLexShortcut{SubSubPrefixNumber}{ch.}[chiffre(s)] \RenewLexShortcut{SubSubPrefixLetter}{let.}[lettre(s)] \RenewLexShortcut{sq}{s.}[et suivant(e)] \RenewLexShortcut{sqq}{ss}[et suivant(e)s] \RenewLexShortcut{analog}{p. an.}[par analogie] \renewrobustcmd{\nomname}{Abr\'eviations} }{} % german CH shortcuts \iftoggle{lexrefCHde}{% \RenewLexShortcut{DispPrefixMain}{Art.}[Artikel(n)]% \RenewLexShortcut{DispsPrefixMain}{Art.}% \RenewLexShortcut{DispPrefixAlt}{\S}% \RenewLexShortcut{DispsPrefixAlt}{\S\S}% \RenewLexShortcut{SubPrefix}{Abs.}[Absatz, -\"{ }e] \RenewLexShortcut{SubSubPrefixNumber}{Ziff.}[Ziffer(n)] \RenewLexShortcut{SubSubPrefixLetter}{lit.}[litera] \RenewLexShortcut{sq}{f.}[und die folgende] \RenewLexShortcut{sqq}{ff.}[und die folgenden] \RenewLexShortcut{analog}{analog} \renewrobustcmd{\nomname}{Abk\"urzungen} }{} % german DE shortcuts \iftoggle{lexrefDE}{% \RenewLexShortcut{DispPrefixMain}{\S}% \RenewLexShortcut{DispsPrefixMain}{\S\S}% \RenewLexShortcut{DispPrefixAlt}{Art.}[Artikel(n)]% \RenewLexShortcut{DispsPrefixAlt}{Art.}% \RenewLexShortcut{SubPrefix}{Abs.}[Absatz, -\"{ }e] \RenewLexShortcut{SubSubPrefixNumber}{Ziff.}[Ziffer(n)] \RenewLexShortcut{SubSubPrefixLetter}{lit.}[litera] \RenewLexShortcut{sq}{f.}[und die folgende] \RenewLexShortcut{sqq}{ff.}[und die folgenden] \RenewLexShortcut{analog}{analog} \renewrobustcmd{\nomname}{Abk\"urzungen} }{} % Latin shortcuts \NewLexShortcut{bis}{$^{bis}$} \NewLexShortcut{ter}{$^{ter}$} \NewLexShortcut{quater}{$^{quater}$} \NewLexShortcut{quinquies}{$^{quinquies}$} \NewLexShortcut{sexies}{$^{sexies}$} \NewLexShortcut{septies}{$^{septies}$} \NewLexShortcut{octies}{$^{octies}$} \NewLexShortcut{nonies}{$^{nonies}$} % FRONT-END USER INTERFACE % #1 = CSname % #2 = Printed Act abbr. % #3 = Act full name % #4 = alt option \newcommandx{\DeclareLex}[4][3,4]{% \protecting{% % 1) Creation of \newindex + toggle for nomenclature, if needed \iftoggle{lexindexing}{\newindex[#3]{#1}}{}% \iftoggle{lexnomencl}{\newtoggle{#1nmcl}\global\togglefalse{#1nmcl}}{}% % 2) Creation of \#1 command \expandafter\newcommandx\csname#1\endcsname[4][2,3,4]{% \ifstrempty{#4}{\togglefalse{lexaltoverride}}{\ifstrequal{#4}{alt}{\toggletrue{lexaltoverride}}{\lexcite@err@invalidthirdarg@DeclareLex}}%Checking whether #4 is blank or set to 'alt', else: error \iftoggle{lexnoprint}{}{\LexRef{#2}{##1}[##2][##3][##4]}% Printing, unless noprint option activated \iftoggle{lexnomencl}{% Entry in nomenclature, if option activated and #3 defined. \ifstrempty{#3}% {}% {\iftoggle{#1nmcl}% {}% {\nomenclature{#2}{#3}\global\toggletrue{#1nmcl}}% }% }% {}% \iftoggle{lexindexing}{\LexIndex{#1}{##1}[##2][##3][##4]{#2}}{}% Indexing, if option activated }% % 3) Creation of \#1ns command \expandafter\newcommandx\csname #1ns\endcsname[4][2,3,4]{% \ifstrempty{#4}{\togglefalse{lexaltoverride}}{\ifstrequal{#4}{alt}{\toggletrue{lexaltoverride}}{\lexcite@err@invalidthirdarg@DeclareLex}}%Checking whether #4 is blank or set to 'alt', else: error \iftoggle{lexnoprint}{}{\LexRefns{#2}{##1}[##2][##3][##4]}% Printing, unless noprint option activated \iftoggle{lexindexing}{\LexIndex{#1}{##1}[##2][##3][##4]{#2}}{}% Indexing, if option activated }% % no need to entry anything in nomenclature here, cause act's name doesn't appear with \#1ns % 4) Creation of \np#1 command \expandafter\newcommandx\csname np#1\endcsname[4][2,3,4]{% % no need to test alt option here, cause no prefix is printed with \np#1 \iftoggle{lexnoprint}{}{\npLexRef{#2}{##1}[##2][##3][##4]}% Printing, unless noprint option activated \iftoggle{lexnomencl}{% Entry in nomenclature, if option activated and #3 defined. \ifstrempty{#3}% {}% {\iftoggle{#1nmcl}% {}% {\nomenclature{#2}{#3}\global\toggletrue{#1nmcl}}% }% }% {}% \iftoggle{lexindexing}{\LexIndex{#1}{##1}[##2][##3][##4]{#2}}{}% Indexing, if option activated }% % 5) Creation of \np#1ns command \expandafter\newcommandx\csname np#1ns\endcsname[4][2,3,4]{% \iftoggle{lexnoprint}{}{\npLexRefns{#2}{##1}[##2][##3][##4]}% Printing, unless noprint option activated \iftoggle{lexindexing}{\LexIndex{#1}{##1}[##2][##3][##4]{#2}}{}% Indexing, if option activated }% % 6) Creation of \idx#1 command \iftoggle{lexindexing}{\expandafter\newcommandx\csname idx#1\endcsname[4][2,3,4]{% \LexIndex{#1}{##1}[##2][##3][##4]{#2}}}{}% Indexing, if option activated }} % PRINTING MACROS % Testing if singular or plural prefix needed \newrobustcmd{\LexRefPrefixTests}[1]{% \IfSubStr{#1}{\sq}% First testing if string contains \psq or \psqq {\toggletrue{lexpluralform}}% if yes, plural form {% else \IfSubStr{#1}{-}% testing if string contains a dash {\toggletrue{lexpluralform}}% if yes, plural form {% else \IfSubStr{#1}{,}% testing if string contains a comma {\toggletrue{lexpluralform}}% if yes, plural form {\togglefalse{lexpluralform}}% else singular form }% }% % Printing MAIN or ALT Prefix depending on lexaltoverride toggle, and singular/plural depending on previous test \iftoggle{lexpluralform}% {\iftoggle{lexaltoverride}% {\DispsPrefixAlt}% {\DispsPrefixMain}% }% {\iftoggle{lexaltoverride}% {\DispPrefixAlt}% {\DispPrefixMain}% }% } % Macro with prefix and suffix % \LexRef and derivates' arguments % #1 = Printed Act's name % #2 = Cited art. number % #3 (optionnal) = paragraph number % #4 (optionnal) = number % #5 (optionnal) = letter \newcommandx{\LexRef}[5][3,4,5]{% \LexRefPrefixTests{#2} % #2% \ifstrempty{#3}{}{ \SubPrefix{} #3}% \ifstrempty{#4}{}{ \SubSubPrefixNumber{} #4}% \ifstrempty{#5}{}{ \SubSubPrefixLetter{} #5}% {} #1% } % Macro with prefix, without suffix \newcommandx{\LexRefns}[5][3,4,5]{% \LexRefPrefixTests{} % #2% \ifstrempty{#3}{}{ \SubPrefix{} #3}% \ifstrempty{#4}{}{ \SubSubPrefixNumber{} #4}% \ifstrempty{#5}{}{ \SubSubPrefixLetter{} #5}% } % Macro without prefix, with suffix \newcommandx{\npLexRef}[5][3,4,5]{% #2% \ifstrempty{#3}{}{ \SubPrefix{} #3}% \ifstrempty{#4}{}{ \SubSubPrefixNumber{} #4}% \ifstrempty{#5}{}{ \SubSubPrefixLetter{} #5}% {} #1% } % Macro without prefix nor suffix \newcommandx{\npLexRefns}[5][3,4,5]{% #2% \ifstrempty{#3}{}{ \SubPrefix{} #3}% \ifstrempty{#4}{}{ \SubSubPrefixNumber{} #4}% \ifstrempty{#5}{}{ \SubSubPrefixLetter{} #5}% } % INDEXING MACRO % \LexIndex arguments % #1 = Act's CSname (= also name of the Act's index) % #2 = Cited art. number % #3 (optionnal) = paragraph number % #4 (optionnal) = number % #5 (optionnal) = letter % #6 = Act's printed abbreviation (to be printed in the index) \newcommandx{\LexIndex}[6][3,4,5]{% % 1) First cleaning \noexpandarg% \IfSubStr{#2}{\sq}% Test \sq {\StrBefore{#2}{\sq}[\lexciteindextempone]\fullexpandarg\StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]\noexpandarg}% if true, take everything before and remove the space {% else \IfSubStr{#2}{\sqq}% Test \sqq {\StrBefore{#2}{\sqq}[\lexciteindextempone]\fullexpandarg\StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]\noexpandarg}% if true, take everything before and remove the space {% \IfSubStr{#2}{-}% Test dash {\StrBefore{#2}{-}[\lexciteindextempone]}% if true, take everything before {\ifdef{\lexciteindextempone}{\renewcommand{\lexciteindextempone}{#2}}{\newcommand{\lexciteindextempone}{#2}}}% }% }% else take everything % 2) Second cleaning \fullexpandarg% %\let\lexciteindextemponenew\lexciteindextempone %\renewcommand{\lexciteindextempone}{\noblanks{\lexciteindextemponenew}}% %%%%%% Remplacer l'escalier ci-dessous par un \loop (Knuth, pp. 217 ss) % \loop A \if B \repeat %\IfInteger{\lexciteindextempone}% Test if integer % {}% if true do nothing % {\loop\StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]\if\ifboolexpr{not test {\IfInteger{\lexciteindextempone}}}{}{}\repeat}% else %% Alternativement: utiliser \whiledo du package ifthen %\IfInteger{\lexciteindextempone}{\setcounter{lexcitecountinteger}{0}}{}%If integer, set counter to zero %\whiledo{\value{lexcitecountinteger}>0}{\StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]\IfInteger{\lexciteindextempone}{\setcounter{lexcitecountinteger}{0}}{}} %%%%%%% If the counter is greater than zero (= macro isn't an integer), remove last char and set counter to zero if macro is now an integer \IfInteger{\lexciteindextempone}% Test if integer {}% if true do nothing {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in string \IfInteger{\lexciteindextempone} {}% if true do nothing {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in string \IfInteger{\lexciteindextempone} {}% {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in string \IfInteger{\lexciteindextempone} {}% {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in string \IfInteger{\lexciteindextempone} {}% {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in string \IfInteger{\lexciteindextempone} {}% {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in string \IfInteger{\lexciteindextempone} {}% {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in string \IfInteger{\lexciteindextempone} {}% {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in stringe \IfInteger{\lexciteindextempone} {}% {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in string \IfInteger{\lexciteindextempone} {}% {% else \StrGobbleRight{\lexciteindextempone}{1}[\lexciteindextempone]% delete last char in string \IfInteger{\lexciteindextempone} {}% {}% }% }% }% }% }% }% }% }% }% }% % 3) Counting the cleaned integer \StrLen{\lexciteindextempone}[\lexciteindextemptwo]% % 4) Proper indexation, sorting (1, 10, 100 or 1000) depending of integer length (1, 2, 3, 4) and of opt args of each entry \ifdefstring{\lexciteindextemptwo}{1}% integer length = 1 {\ifboolexpr{% if #3, #4 and #5 are defined not test {\ifstrempty{#3}}% and% not test {\ifstrempty{#4}}% and% not test {\ifstrempty{#5}}% }% {\sindex[#1]{1@#6 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry {% \sindex[#1]{1@#6 #2% else: indexing everything \ifstrempty{#3}{}{!-- \SubPrefix{} #3}% \ifstrempty{#4}{}{!-- \SubSubPrefixNumber{} #4}% \ifstrempty{#5}{}{!-- \SubSubPrefixLetter{} #5}% }}% }% {\ifdefstring{\lexciteindextemptwo}{2}% integer length = 2 {\ifboolexpr{% if #3, #4 and #5 are defined not test {\ifstrempty{#3}}% and% not test {\ifstrempty{#4}}% and% not test {\ifstrempty{#5}}% }% {\sindex[#1]{10@#6 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry {% \sindex[#1]{10@#6 #2% else: indexing everything \ifstrempty{#3}{}{!-- \SubPrefix{} #3}% \ifstrempty{#4}{}{!-- \SubSubPrefixNumber{} #4}% \ifstrempty{#5}{}{!-- \SubSubPrefixLetter{} #5}% }}% }% {\ifdefstring{\lexciteindextemptwo}{3}% integer length = 3 {\ifboolexpr{% if #3, #4 and #5 are defined not test {\ifstrempty{#3}}% and% not test {\ifstrempty{#4}}% and% not test {\ifstrempty{#5}}% }% {\sindex[#1]{100@#6 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry {% \sindex[#1]{100@#6 #2% else: indexing everything \ifstrempty{#3}{}{!-- \SubPrefix{} #3}% \ifstrempty{#4}{}{!-- \SubSubPrefixNumber{} #4}% \ifstrempty{#5}{}{!-- \SubSubPrefixLetter{} #5}% }}% }% {\ifdefstring{\lexciteindextemptwo}{4}% integer length = 4 {\ifboolexpr{% if #3, #4 and #5 are defined not test {\ifstrempty{#3}}% and% not test {\ifstrempty{#4}}% and% not test {\ifstrempty{#5}}% }% {\sindex[#1]{1000@#6 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry {% \sindex[#1]{1000@#6 #2% else: indexing everything \ifstrempty{#3}{}{!-- \SubPrefix{} #3}% \ifstrempty{#4}{}{!-- \SubSubPrefixNumber{} #4}% \ifstrempty{#5}{}{!-- \SubSubPrefixLetter{} #5}% }}% }% {\ifdefstring{\lexciteindextemptwo}{5}% integer length = 5 {\ifboolexpr{% if #3, #4 and #5 are defined not test {\ifstrempty{#3}}% and% not test {\ifstrempty{#4}}% and% not test {\ifstrempty{#5}}% }% {\sindex[#1]{10000@#6 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry {% \sindex[#1]{10000@#6 #2% else: indexing everything \ifstrempty{#3}{}{!-- \SubPrefix{} #3}% \ifstrempty{#4}{}{!-- \SubSubPrefixNumber{} #4}% \ifstrempty{#5}{}{!-- \SubSubPrefixLetter{} #5}% }}% }% {}% }% }% }% }% } \endinput