%------------ identification --------------
\ProvidesPackage{lexref}[2014/01/21 v1.0.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}{%
Third 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}%\robustify{\nomenclature}}
\DeclareOption{CHfr}{\toggletrue{lexrefCHfr}}
\DeclareOption{CHde}{\toggletrue{lexrefCHde}}
\DeclareOption{DE}{\toggletrue{lexrefDE}}
%------------ execution of options --------------
\ProcessOptions
%------------ main code --------------
% DEFINITION OF LITERAL PREFIXES AND SHORTCUTS
\newcommandx{\NewLexShortcut}[3][3]{%
\ifdef{#1}{% This test makes sure an already defined command is overrided, ensuring the nomenclature tests will work properly
\renewrobustcmd{#1}{#2%
\iftoggle{lexshortcutstolist}{% Entry in nomenclature, if option activated and #3 defined.
	\ifstrempty{#3}%
		{}%
		{\ifcsdef{nomalreadydef#2}% Nomencl crashes if the same act is already passed to \nomenclature in another page, so this test ensures it won't be passed more than once
			{}%
			{%
			\nomenclature{#2}{#3}%
			\expandafter\newcommand\csname nomalreadydef#2\endcsname\relax%
			}%
		}%
	}%
	{}% 
}}%
{%
\newrobustcmd{#1}{#2%
\iftoggle{lexshortcutstolist}{% Entry in nomenclature, if option activated and #3 defined.
	\ifstrempty{#3}%
		{}%
		{\ifcsdef{nomalreadydef#2}% Nomencl crashes if the same act is already passed to \nomenclature in another page, so this test ensures it won't be passed more than once
			{}%
			{%
			\nomenclature{#2}{#3}%
			\expandafter\newcommand\csname nomalreadydef#2\endcsname\relax%
			}%
		}%
	}%
	{}% 
}}%
}%
% Following shortcuts may be redefined using \RenewLexShortcut 
\newcommandx{\RenewLexShortcut}[3][3]{%
\renewrobustcmd{#1}{#2%
\iftoggle{lexshortcutstolist}{% Entry in nomenclature, if option activated and #3 defined.
	\ifstrempty{#3}%
		{}%
		{\ifcsdef{nomalreadydef#2}% Nomencl crashes if the same act is already passed to \nomenclature in another page, so this test ensures it won't be passed more than once
			{}%
			{%
			\nomenclature{#2}{#3}%
			\expandafter\newcommand\csname nomalreadydef#2\endcsname\relax%
			}%
		}%
	}%
	{}% 
}}
% 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 = Act abbr.
 % #2 = Act full name
 % #3 = alt option
 
\newcommandx{\DeclareLex}[3][2,3]{%
\protecting{%
% 1) Creation of \newindex, if needed
\iftoggle{lexindexing}{\newindex[#2]{#1}}{}%
% 2) Creation of \#1 command
\expandafter\newcommandx\csname#1\endcsname[4][2,3,4]{%
\ifstrempty{#3}{\togglefalse{lexaltoverride}}{\ifstrequal{#3}{alt}{\toggletrue{lexaltoverride}}{\lexcite@err@invalidthirdarg@DeclareLex}}%Checking whether #3 is blank or set to 'alt', else: error
\iftoggle{lexnoprint}{}{\LexRef{#1}{##1}[##2][##3][##4]}% Printing, unless noprint option activated
\iftoggle{lexnomencl}{% Entry in nomenclature, if option activated and #2 defined.
	\ifstrempty{#2}%
		{}%
		{\ifcsdef{nomalreadydef#1}% Nomencl crashes if the same act is already passed to \nomenclature in another page, so this test ensures it won't be passed more than once
			{}%
			{%
			\nomenclature{#1}{#2}%
			\expandafter\newcommand\csname nomalreadydef#1\endcsname\relax}%
		}%
	}%
	{}% 
\iftoggle{lexindexing}{\LexIndex{#1}{##1}[##2][##3][##4]}{}% Indexing, if option activated
}%
% 3) Creation of \#1ns command
\expandafter\newcommandx\csname #1ns\endcsname[4][2,3,4]{%
\ifstrempty{#3}{\togglefalse{lexaltoverride}}{\ifstrequal{#3}{alt}{\toggletrue{lexaltoverride}}{\lexcite@err@invalidthirdarg@DeclareLex}}%Checking whether #3 is blank or set to 'alt', else: error
\iftoggle{lexnoprint}{}{\LexRefns{#1}{##1}[##2][##3][##4]}% Printing, unless noprint option activated
\iftoggle{lexindexing}{\LexIndex{#1}{##1}[##2][##3][##4]}{}% Indexing, if option activated
}%
% 4) Creation of \np#1 command
\expandafter\newcommandx\csname np#1\endcsname[4][2,3,4]{%
\iftoggle{lexnoprint}{}{\npLexRef{#1}{##1}[##2][##3][##4]}% Printing, unless noprint option activated
\iftoggle{lexnomencl}{% Entry in nomenclature, if option activated and #2 defined.
	\ifstrempty{#2}%
		{}%
		{\ifcsdef{nomalreadydef#1}% Nomencl crashes if the same act is already passed to \nomenclature in another page, so this test ensures it won't be passed more than once
			{}%
			{%
			\nomenclature{#1}{#2}%
			\expandafter\newcommand\csname nomalreadydef#1\endcsname\relax}%
		}%
	}%
	{}% 
\iftoggle{lexindexing}{\LexIndex{#1}{##1}[##2][##3][##4]}{}% Indexing, if option activated
}%
% 5) Creation of \np#1ns command
\expandafter\newcommandx\csname np#1ns\endcsname[4][2,3,4]{%
\iftoggle{lexnoprint}{}{\npLexRefns{#1}{##1}[##2][##3][##4]}% Printing, unless noprint option activated
\iftoggle{lexindexing}{\LexIndex{#1}{##1}[##2][##3][##4]}{}% 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]}}{}% Indexing, if option activated
}} 

% PRINTING MACROS

\newrobustcmd{\LexRefPrefixTests}[1]{%
% Testing if singular or plural profix needed
\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, and singular/plural depending on previous test
\iftoggle{lexpluralform}%
	{\iftoggle{lexaltoverride}%
		{\DispsPrefixAlt}%
		{\DispsPrefixMain}%
	}%
	{\iftoggle{lexaltoverride}%
		{\DispPrefixAlt}%
		{\DispPrefixMain}%
	}%
}

% Macro with prefix and suffix
\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

\newcommandx{\LexIndex}[5][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@#1 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry
		{%
		\sindex[#1]{1@#1 #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@#1 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry
			{%
			\sindex[#1]{10@#1 #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@#1 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry
				{%
				\sindex[#1]{100@#1 #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@#1 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry
					{%
					\sindex[#1]{1000@#1 #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@#1 #2!-- \SubPrefix{} #3}}% index only takes #3 as subentry
						{%
						\sindex[#1]{10000@#1 #2% else: indexing everything
						\ifstrempty{#3}{}{!-- \SubPrefix{} #3}% 
						\ifstrempty{#4}{}{!-- \SubSubPrefixNumber{} #4}%
						\ifstrempty{#5}{}{!-- \SubSubPrefixLetter{} #5}%
						}}%
						}%
						{}%
				}%
			}%
		}%
	}%
}

\endinput