Complete rewrite to support Unicode OpenType fonts and LaTeX3
1 parent 50da92a commit 226ea9b9949d09ce79d68f334a1c6e53fad19c44
Nigel Stanger authored on 13 Dec
Showing 1 changed file
View
403
relalg.sty
\def\packagedate{13 December 2024}
\def\packageversion{2.0}
\def\packageshortdate{2024/12/13}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Defines various relational algebra symbols.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Version History
% v1.0 Initial version.
% v2.0 Complete rewrite to support Unicode OpenType fonts and LaTeX3.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
\NeedsTeXFormat{LaTeX2e}[2001/06/01]
\ProvidesPackage{relalg}[2008/02/28 Relational algebra notation]
 
\RequirePackage{amssymb}
\RequirePackage{latexsym}
\RequirePackage{graphics}
% Graphics is needed so that we can scale the size of a couple of operators.
\ProvidesPackage{relalg}%
[\packageshortdate\space v\packageversion\space Relational algebra notation]
 
 
\RequirePackage{amsmath}
\RequirePackage{expl3}
\RequirePackage{iftex}
 
 
\ExplSyntaxOn
\bool_new:N \__unicode_engine
 
\ifLuaTeX
\PackageInfo{relalg}{LuaTeX\space engine\space detected}
\bool_set_true:N \__unicode_engine
\fi
 
\ifXeTeX
\PackageInfo{relalg}{XeTeX\space engine\space detected}
\bool_set_true:N \__unicode_engine
\fi
 
\bool_if:NTF \__unicode_engine {
\RequirePackage[no-math]{fontspec}
\RequirePackage{unicode-math}
 
\setmathfont{latinmodern-math.otf}
 
% The various join symbols aren't covered very well by many maths fonts
% (including Latin Modern Math, annoyingly), so let's Frankenstein them
% in from fonts that do have them. We need to hack the scale to get roughly
% proportional looking sizes.
% Outer joins (left, right, full):
\setmathfont{STIXTwoMath-Regular.otf}[range={"027D5-"027D7}, Scale=0.875]
% Inner join: (1.143 = 1 / 0.875)
\setmathfont{KpMath-Light.otf}[range={"02A1D}, Scale=1.143]
}{
\PackageInfo{relalg}{non-Unicode\space engine\space detected}
\RequirePackage{latexsym} % for \Join
}
\ExplSyntaxOff
 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% IDENTIFIERS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
% General identifiers.
\NewDocumentCommand{\RelIdentifier}{m}{\ensuremath{\mathit{#1}}}
 
% Attribute names.
\let\RelAttribute\RelIdentifier
\let\RelAttr\RelIdentifier
 
% Relation variable names.
\let\RelVariable\RelIdentifier
\let\RelVar\RelIdentifier
 
% Attribute sets: \RelAttributeSet{foo,bar,baz}, \RelAttrSet{foo,bar,baz}
% <https://tex.stackexchange.com/a/159132>, expl3 manual Section 23
\ExplSyntaxOn
\NewDocumentCommand{\RelAttributeSet}{m}{
\clist_clear:N \l_tmpa_clist
\clist_map_inline:nn{#1}{
\clist_put_right:Nn \l_tmpa_clist {\RelAttribute{##1}}
}
\ensuremath{\{\clist_use:Nn \l_tmpa_clist {,}\}}
}
\let\RelAttrSet\RelAttributeSet
\ExplSyntaxOff
 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% BASIC OPERATORS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% select or restrict operator
\newcommand{\RelSelect}{\ensuremath{\sigma}}
\newcommand{\RelRestrict}{\RelSelect}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% project operator
\newcommand{\RelProject}{\ensuremath{\pi}}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% set union operator
\newcommand{\RelUnion}{\ensuremath{\cup}}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% set difference operator
\newcommand{\RelDifference}{\ensuremath{-}}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% cartesian product operator
\newcommand{\RelProduct}{\ensuremath{\times}}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rename operator
\newcommand{\RelRename}{\ensuremath{\rho}}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% extend operator
\newcommand{\RelExtend}{\ensuremath{\epsilon}}
% Restrict (select) operator.
\NewDocumentCommand{\RelRestrict}{}{\ensuremath{\sigma}}
\let\RelSelect\RelRestrict
 
% Project operator.
\NewDocumentCommand{\RelProject}{}{\ensuremath{\pi}}
 
% Set union operator.
\NewDocumentCommand{\RelUnion}{}{\ensuremath{\cup}}
 
% Set difference operator.
\NewDocumentCommand{\RelDifference}{}{\ensuremath{-}}
\let\RelMinus\RelDifference
 
% Cartesian product operator.
\NewDocumentCommand{\RelCartesianProduct}{}{\ensuremath{\times}}
\let\RelProduct\RelCartesianProduct
\let\RelTimes\RelCartesianProduct
 
% Rename operator.
\NewDocumentCommand{\RelRename}{}{\ensuremath{\rho}}
 
% Extend operator.
\NewDocumentCommand{\RelExtend}{}{\ensuremath{\epsilon}}
 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ADDITIONAL OPERATORS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% set intersection operator
\newcommand{\RelIntersection}{\ensuremath{\cap}}
\newcommand{\RelIntersect}{\RelIntersection}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% natural join operator
\newcommand{\RelNaturalJoin}{\ensuremath{\Join}}
\newcommand{\RelNatJoin}{\RelNatJoin}
\newcommand{\RelNJoin}{\RelNJoin}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% division operators
\newcommand{\RelDivide}{\ensuremath{/}}
\newcommand{\RelAltDivide}{\ensuremath{\div}}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% assignment operator
\newcommand{\RelAssign}{\ensuremath{\leftarrow}}
% Set intersection operator.
\NewDocumentCommand{\RelIntersection}{}{\ensuremath{\cap}}
\let\RelIntersect\RelIntersection
 
% Join operator (including natural join).
% For some reason XeTeX puts less space in front of the operator than LuaTeX.
% Adding +2.5mu for XeTeX looks close enough to LuaTeX's output. This also
% applies to the outer join operators below.
\NewDocumentCommand{\RelJoin}{}{\ensuremath{\ifXeTeX\mkern2.5mu\fi\mathbin{\Join}}}
\let\RelNaturalJoin\RelJoin
\let\RelNatJoin\RelJoin
\let\RelNJoin\RelJoin
 
% Division operator (two alternatives).
\NewDocumentCommand{\RelDivide}{}{\ensuremath{/}}
\NewDocumentCommand{\RelAltDivide}{}{\ensuremath{\div}}
 
% Assignment operator.
\NewDocumentCommand{\RelAssign}{}{\ensuremath{\leftarrow}}
 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% EXTENDED OPERATORS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% aggregate functions
\newcommand{\RelAggregrate}[2]{\ensuremath{\mathcal{G}_{\mathbf{\mathrm{#1}}(#2)}}}
\newcommand{\RelSum}[1]{\RelAggregrate{sum}{#1}}
\newcommand{\RelAvg}[1]{\RelAggregrate{avg}{#1}}
\newcommand{\RelMin}[1]{\RelAggregrate{min}{#1}}
\newcommand{\RelMax}[1]{\RelAggregrate{max}{#1}}
\newcommand{\RelCount}[1]{\RelAggregrate{count}{#1}}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% outer join operators
% Note: can't use \ensuremath in these because it screws up the spacing.
% The $ are OK though because they're used inside hboxes anyway.
\newcommand{\RelLeftOuterJoin}{\scalebox{0.5}[1]{$\sqsupset$}\mkern-2.5mu\lower0.1em\hbox{$\Join$}}
\newcommand{\RelleftOuterJoin}{\RelLeftOuterJoin}
\newcommand{\RelLOuterJoin}{\RelLeftOuterJoin}
\newcommand{\RelLeftOuter}{\RelLeftOuterJoin}
\newcommand{\RelLOJ}{\RelLeftOuterJoin}
 
\newcommand{\RelRightOuterJoin}{\lower0.1em\hbox{$\Join$}\mkern-2.5mu\scalebox{0.5}[1]{$\sqsubset$}}
\newcommand{\RelrightOuterJoin}{\RelRightOuterJoin}
\newcommand{\RelROuterJoin}{\RelRightOuterJoin}
\newcommand{\RelRightOuter}{\RelRightOuterJoin}
\newcommand{\RelROJ}{\RelRightOuterJoin}
 
\newcommand{\RelFullOuterJoin}{\scalebox{0.5}[1]{$\sqsupset$}\mkern-2.5mu\lower0.1em\hbox{$\Join$}\mkern-2.5mu\scalebox{0.5}[1]{$\sqsubset$}}
\newcommand{\RelfullOuterJoin}{\RelFullOuterJoin}
\newcommand{\RelFOuterJoin}{\RelFullOuterJoin}
\newcommand{\RelFullOuter}{\RelFullOuterJoin}
\newcommand{\RelFOJ}{\RelFullOuterJoin}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% semijoin operator
\newcommand{\RelSemiJoin}{\ensuremath{\ltimes}}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% antijoin operator
\newcommand{\RelAntiJoin}{\ensuremath{\triangleright}}
% Aggregate functions.
\DeclareMathOperator{\AggAvg}{avg}
\DeclareMathOperator{\AggCount}{count}
\DeclareMathOperator{\AggMin}{min}
\DeclareMathOperator{\AggMax}{max}
\DeclareMathOperator{\AggSum}{sum}
 
\NewDocumentCommand{\RelAggregrate}{m m}{\ensuremath{\mathcal{G}_{#1}(#2)}}
 
\NewDocumentCommand{\RelAverage}{m}{\RelAggregrate{\AggAverage}{#1}}
\let\RelAvg\RelAverage
 
\NewDocumentCommand{\RelCount}{m}{\RelAggregrate{\AggCount}{#1}}
 
\NewDocumentCommand{\RelMaximum}{m}{\RelAggregrate{\AggMax}{#1}}
\let\RelMax\RelMaximum
 
\NewDocumentCommand{\RelMinimum}{m}{\RelAggregrate{\AggMin}{#1}}
\let\RelMin\RelMinimum
 
\NewDocumentCommand{\RelSum}{m}{\RelAggregrate{\AggSum}{#1}}
 
% Outer join operators.
\ExplSyntaxOn
\bool_if:NTF \__unicode_engine {
\NewDocumentCommand{\RelLeftOuterJoin}{}{\ensuremath{\ifXeTeX\mkern2.5mu\fi\mathbin{\leftouterjoin}}}
\NewDocumentCommand{\RelRightOuterJoin}{}{\ensuremath{\ifXeTeX\mkern2.5mu\fi\mathbin{\rightouterjoin}}}
\NewDocumentCommand{\RelFullOuterJoin}{}{\ensuremath{\ifXeTeX\mkern2.5mu\fi\mathbin{\fullouterjoin}}}
}{
% Hand-tweaked for non-Unicode engines based on answers at
% <https://tex.stackexchange.com/questions/20740/symbols-for-outer-joins>
% Weirdly the height of \Join is fractionally shorter than \bowtie, so
% we can't use the more sensible solution of measuring off the line
% height. Use only font-relative units to ensure proper scaling.
\def\__ojoin{\rule[0.11ex]{0.25em}{0.1ex}\llap{\rule[1.41ex]{0.25em}{0.1ex}}}
\NewDocumentCommand{\RelLeftOuterJoin}{}{\ensuremath{\mathbin{\__ojoin\mkern-6.4mu\Join}}}
\NewDocumentCommand{\RelRightOuterJoin}{}{\ensuremath{\mathbin{\Join\mkern-6.4mu\__ojoin}}}
\NewDocumentCommand{\RelFullOuterJoin}{}{\ensuremath{\mathbin{\__ojoin\mkern-6.4mu\Join\mkern-6.4mu\__ojoin}}}
}
\ExplSyntaxOff
 
\let\RelLOuterJoin\RelLeftOuterJoin
\let\RelLeftOuter\RelLeftOuterJoin
\let\RelLOJ\RelLeftOuterJoin
 
\let\RelROuterJoin\RelRightOuterJoin
\let\RelRightOuter\RelRightOuterJoin
\let\RelROJ\RelRightOuterJoin
 
\let\RelFOuterJoin\RelFullOuterJoin
\let\RelFullOuter\RelFullOuterJoin
\let\RelFOJ\RelFullOuterJoin
 
% Semijoin operator.
\NewDocumentCommand{\RelLeftSemiJoin}{}{\ensuremath{\ltimes}}
\let\RelSemiJoin\RelLeftSemiJoin
 
\NewDocumentCommand{\RelRightSemiJoin}{}{\ensuremath{\rtimes}}
\let\RelReverseSemiJoin\RelRightSemiJoin
 
% Antijoin operator.
\NewDocumentCommand{\RelLeftAntiJoin}{}{\ensuremath{\triangleright}}
\let\RelAntiJoin\RelLeftAntiJoin
 
\NewDocumentCommand{\RelRightAntiJoin}{}{\ensuremath{\triangleleft}}
\let\RelReverseAntiJoin\RelRightAntiJoin
 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MISCELLANEOUS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% logical operators
% \And appears to conflict with beamer? (unconfirmed)
\newcommand{\RelLogicalAnd}{\ensuremath{\wedge}}
\newcommand{\RelLogAnd}{\RelLogicalAnd}
 
\newcommand{\RelLogicalOr}{\ensuremath{\vee}}
\newcommand{\RelLogOr}{\RelLogicalOr}
 
\newcommand{\RelLogicalNot}{\ensuremath{\neg}}
\newcommand{\RelLogNot}{\RelLogicalNot}
% Logical operators.
\NewDocumentCommand{\RelLogicalAnd}{}{\ensuremath{\wedge}}
\let\RelLogAnd\RelLogicalAnd
\let\RelAnd\RelLogicalAnd
 
\NewDocumentCommand{\RelLogicalOr}{}{\ensuremath{\vee}}
\let\RelLogOr\RelLogicalOr
\let\RelOr\RelLogicalOr
 
\NewDocumentCommand{\RelLogicalNot}{}{\ensuremath{\neg}}
\let\RelLogNot\RelLogicalNot
\let\RelNot\RelLogicalNot
 
\endinput