%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