mathpartir.sty 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. %%
  2. %% This is the original source file mathpar.sty
  3. %%
  4. %% Package `mathpar' to use with LaTeX 2e
  5. %% Copyright Didier Remy, all rights reserved.
  6. \NeedsTeXFormat{LaTeX2e}
  7. \ProvidesPackage{mathpartir}
  8. [2001/23/02 v0.92 Math Paragraph for Type Inference Rules]
  9. %%
  10. %% Identification
  11. %% Preliminary declarations
  12. \RequirePackage {keyval}
  13. %% Options
  14. %% More declarations
  15. %% PART I: Typesetting maths in paragraphe mode
  16. \newdimen \mpr@tmpdim
  17. % To ensure hevea \hva compatibility, \hva should expands to nothing
  18. % in mathpar or in mathrule
  19. \let \mpr@hva \empty
  20. %% normal paragraph parametters, should rather be taken dynamically
  21. \def \mpr@savepar {%
  22. \edef \MathparNormalpar
  23. {\noexpand \lineskiplimit \the\lineskiplimit
  24. \noexpand \lineskip \the\lineskip}%
  25. }
  26. \def \mpr@rulelineskip {\lineskiplimit=0.3em\lineskip=0.2em plus 0.1em}
  27. \def \mpr@lesslineskip {\lineskiplimit=0.6em\lineskip=0.5em plus 0.2em}
  28. \def \mpr@lineskip {\lineskiplimit=1.2em\lineskip=1.2em plus 0.2em}
  29. \let \MathparLineskip \mpr@lineskip
  30. \def \mpr@paroptions {\MathparLineskip}
  31. \let \mpr@prebindings \relax
  32. \newskip \mpr@andskip \mpr@andskip 2em plus 0.5fil minus 0.5em
  33. \def \mpr@goodbreakand
  34. {\hskip -\mpr@andskip \penalty -1000\hskip \mpr@andskip}
  35. \def \mpr@and {\hskip \mpr@andskip}
  36. \def \mpr@andcr {\penalty 50\mpr@and}
  37. \def \mpr@cr {\penalty -10000\mpr@and}
  38. \def \mpr@eqno #1{\mpr@andcr #1\hskip 0em plus -1fil \penalty 10}
  39. \def \mpr@bindings {%
  40. \let \and \mpr@andcr
  41. \let \par \mpr@andcr
  42. \let \\\mpr@cr
  43. \let \eqno \mpr@eqno
  44. \let \hva \mpr@hva
  45. }
  46. \let \MathparBindings \mpr@bindings
  47. % \@ifundefined {ignorespacesafterend}
  48. % {\def \ignorespacesafterend {\aftergroup \ignorespaces}
  49. \newenvironment{mathpar}[1][]
  50. {$$\mpr@savepar \parskip 0em \hsize \linewidth \centering
  51. \vbox \bgroup \mpr@prebindings \mpr@paroptions #1\ifmmode $\else
  52. \noindent $\displaystyle\fi
  53. \MathparBindings}
  54. {\unskip \ifmmode $\fi\egroup $$\ignorespacesafterend}
  55. % \def \math@mathpar #1{\setbox0 \hbox {$\displaystyle #1$}\ifnum
  56. % \wd0 < \hsize $$\box0$$\else \bmathpar #1\emathpar \fi}
  57. %%% HOV BOXES
  58. \def \mathvbox@ #1{\hbox \bgroup \mpr@normallineskip
  59. \vbox \bgroup \tabskip 0em \let \\ \cr
  60. \halign \bgroup \hfil $##$\hfil\cr #1\crcr \egroup \egroup
  61. \egroup}
  62. \def \mathhvbox@ #1{\setbox0 \hbox {\let \\\qquad $#1$}\ifnum \wd0 < \hsize
  63. \box0\else \mathvbox {#1}\fi}
  64. %% Part II -- operations on lists
  65. \newtoks \mpr@lista
  66. \newtoks \mpr@listb
  67. \long \def\mpr@cons #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter
  68. {#2}\edef #2{\the \mpr@lista \the \mpr@listb}}
  69. \long \def\mpr@snoc #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter
  70. {#2}\edef #2{\the \mpr@listb\the\mpr@lista}}
  71. \long \def \mpr@concat#1=#2\mpr@to#3{\mpr@lista \expandafter {#2}\mpr@listb
  72. \expandafter {#3}\edef #1{\the \mpr@listb\the\mpr@lista}}
  73. \def \mpr@head #1\mpr@to #2{\expandafter \mpr@head@ #1\mpr@head@ #1#2}
  74. \long \def \mpr@head@ #1#2\mpr@head@ #3#4{\def #4{#1}\def#3{#2}}
  75. \def \mpr@flatten #1\mpr@to #2{\expandafter \mpr@flatten@ #1\mpr@flatten@ #1#2}
  76. \long \def \mpr@flatten@ \\#1\\#2\mpr@flatten@ #3#4{\def #4{#1}\def #3{\\#2}}
  77. \def \mpr@makelist #1\mpr@to #2{\def \mpr@all {#1}%
  78. \mpr@lista {\\}\mpr@listb \expandafter {\mpr@all}\edef \mpr@all {\the
  79. \mpr@lista \the \mpr@listb \the \mpr@lista}\let #2\empty
  80. \def \mpr@stripof ##1##2\mpr@stripend{\def \mpr@stripped{##2}}\loop
  81. \mpr@flatten \mpr@all \mpr@to \mpr@one
  82. \expandafter \mpr@snoc \mpr@one \mpr@to #2\expandafter \mpr@stripof
  83. \mpr@all \mpr@stripend
  84. \ifx \mpr@stripped \empty \let \mpr@isempty 0\else \let \mpr@isempty 1\fi
  85. \ifx 1\mpr@isempty
  86. \repeat
  87. }
  88. %% Part III -- Type inference rules
  89. \def \mpr@rev #1\mpr@to #2{\let \mpr@tmp \empty
  90. \def \\##1{\mpr@cons ##1\mpr@to \mpr@tmp}#1\let #2\mpr@tmp}
  91. \newif \if@premisse
  92. \newbox \mpr@hlist
  93. \newbox \mpr@vlist
  94. \newif \ifmpr@center \mpr@centertrue
  95. \def \mpr@htovlist {%
  96. \setbox \mpr@hlist
  97. \hbox {\strut
  98. \ifmpr@center \hskip -0.5\wd\mpr@hlist\fi
  99. \unhbox \mpr@hlist}%
  100. \setbox \mpr@vlist
  101. \vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist
  102. \else \unvbox \mpr@vlist \box \mpr@hlist
  103. \fi}%
  104. }
  105. % OLD version
  106. % \def \mpr@htovlist {%
  107. % \setbox \mpr@hlist
  108. % \hbox {\strut \hskip -0.5\wd\mpr@hlist \unhbox \mpr@hlist}%
  109. % \setbox \mpr@vlist
  110. % \vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist
  111. % \else \unvbox \mpr@vlist \box \mpr@hlist
  112. % \fi}%
  113. % }
  114. \def \mpr@sep{2em}
  115. \def \mpr@blank { }
  116. \def \mpr@hovbox #1#2{\hbox
  117. \bgroup
  118. \ifx #1T\@premissetrue
  119. \else \ifx #1B\@premissefalse
  120. \else
  121. \PackageError{mathpartir}
  122. {Premisse orientation should either be P or B}
  123. {Fatal error in Package}%
  124. \fi \fi
  125. \def \@test {#2}\ifx \@test \mpr@blank\else
  126. \setbox \mpr@hlist \hbox {}%
  127. \setbox \mpr@vlist \vbox {}%
  128. \if@premisse \let \snoc \mpr@cons \else \let \snoc \mpr@snoc \fi
  129. \let \@hvlist \empty \let \@rev \empty
  130. \mpr@tmpdim 0em
  131. \expandafter \mpr@makelist #2\mpr@to \mpr@flat
  132. \if@premisse \mpr@rev \mpr@flat \mpr@to \@rev \else \let \@rev \mpr@flat \fi
  133. \def \\##1{%
  134. \def \@test {##1}\ifx \@test \empty
  135. \mpr@htovlist
  136. \mpr@tmpdim 0em %%% last bug fix not extensively checked
  137. \else
  138. \setbox0 \hbox{$\displaystyle {##1}$}\relax
  139. \advance \mpr@tmpdim by \wd0
  140. %\mpr@tmpdim 1.02\mpr@tmpdim
  141. \ifnum \mpr@tmpdim < \hsize
  142. \ifnum \wd\mpr@hlist > 0
  143. \if@premisse
  144. \setbox \mpr@hlist
  145. \hbox {\unhbox0 \hskip \mpr@sep \unhbox \mpr@hlist}%
  146. \else
  147. \setbox \mpr@hlist
  148. \hbox {\unhbox \mpr@hlist \hskip \mpr@sep \unhbox0}%
  149. \fi
  150. \else
  151. \setbox \mpr@hlist \hbox {\unhbox0}%
  152. \fi
  153. \else
  154. \ifnum \wd \mpr@hlist > 0
  155. \mpr@htovlist
  156. \mpr@tmpdim \wd0
  157. \fi
  158. \setbox \mpr@hlist \hbox {\unhbox0}%
  159. \fi
  160. \advance \mpr@tmpdim by \mpr@sep
  161. \fi
  162. }%
  163. \@rev
  164. \mpr@htovlist
  165. \ifmpr@center \hskip \wd\mpr@vlist\fi \box \mpr@vlist
  166. \fi
  167. \egroup
  168. }
  169. %%% INFERENCE RULES
  170. \@ifundefined{@@over}{%
  171. \let\@@over\over % fallback if amsmath is not loaded
  172. \let\@@overwithdelims\overwithdelims
  173. \let\@@atop\atop \let\@@atopwithdelims\atopwithdelims
  174. \let\@@above\above \let\@@abovewithdelims\abovewithdelims
  175. }{}
  176. \def \mpr@@fraction #1#2{\hbox {\advance \hsize by -0.5em
  177. $\displaystyle {#1\@@over #2}$}}
  178. \let \mpr@fraction \mpr@@fraction
  179. \def \mpr@@reduce #1#2{\hbox
  180. {$\lower 0.01pt \mpr@@fraction {#1}{#2}\mkern -15mu\rightarrow$}}
  181. \def \mpr@@rewrite #1#2#3{\hbox
  182. {$\lower 0.01pt \mpr@@fraction {#2}{#3}\mkern -8mu#1$}}
  183. \def \mpr@infercenter #1{\vcenter {\mpr@hovbox{T}{#1}}}
  184. \def \mpr@empty {}
  185. \def \mpr@inferrule
  186. {\bgroup
  187. \ifnum \linewidth<\hsize \hsize \linewidth\fi
  188. \mpr@rulelineskip
  189. \let \and \qquad
  190. \let \hva \mpr@hva
  191. \let \@rulename \mpr@empty
  192. \let \@rule@options \mpr@empty
  193. \mpr@inferrule@}
  194. \newcommand {\mpr@inferrule@}[3][]
  195. {\everymath={\displaystyle}%
  196. \def \@test {#2}\ifx \empty \@test
  197. \setbox0 \hbox {$\vcenter {\mpr@hovbox{B}{#3}}$}%
  198. \else
  199. \def \@test {#3}\ifx \empty \@test
  200. \setbox0 \hbox {$\vcenter {\mpr@hovbox{T}{#2}}$}%
  201. \else
  202. \setbox0 \mpr@fraction {\mpr@hovbox{T}{#2}}{\mpr@hovbox{B}{#3}}%
  203. \fi \fi
  204. \def \@test {#1}\ifx \@test\empty \box0
  205. \else \vbox
  206. %%% Suggestion de Francois pour les etiquettes longues
  207. %%% {\hbox to \wd0 {\RefTirName {#1}\hfil}\box0}\fi
  208. {\hbox {\RefTirName {#1}}\box0}\fi
  209. \egroup}
  210. \def \mpr@vdotfil #1{\vbox to #1{\leaders \hbox{$\cdot$} \vfil}}
  211. % They are two forms
  212. % \mathrule [label]{[premisses}{conclusions}
  213. % or
  214. % \mathrule* [options]{[premisses}{conclusions}
  215. %
  216. % Premisses and conclusions are lists of elements separated by \\
  217. % Each \\ produces a break, attempting horizontal breaks if possible,
  218. % and vertical breaks if needed.
  219. %
  220. % An empty element obtained by \\\\ produces a vertical break in all cases.
  221. %
  222. % The former rule is aligned on the fraction bar.
  223. % The optional label appears on top of the rule
  224. % The second form to be used in a derivation tree is aligned on the last
  225. % line of its conclusion
  226. %
  227. % The second form can be parameterized, using the key=val interface. The
  228. % folloiwng keys are recognized:
  229. %
  230. % width set the width of the rule to val
  231. % narrower set the width of the rule to val\hsize
  232. % before execute val at the beginning/left
  233. % lab put a label [Val] on top of the rule
  234. % lskip add negative skip on the right
  235. % llab put a left label [Val], ignoring its width
  236. % left put a left label [Val]
  237. % right put a right label [Val]
  238. % rlab put a right label [Val], ignoring its width
  239. % rskip add negative skip on the left
  240. % vdots lift the rule by val and fill vertical space with dots
  241. % after execute val at the end/right
  242. %
  243. % Note that most options must come in this order to avoid strange
  244. % typesetting (in particular lskip must preceed left and llab and
  245. % rskip must follow rlab or right; vdots must come last or be followed by
  246. % rskip.
  247. %
  248. \define@key {mprset}{flushleft}[]{\mpr@centerfalse}
  249. \define@key {mprset}{center}[]{\mpr@centertrue}
  250. \def \mprset #1{\setkeys{mprset}{#1}}
  251. \newbox \mpr@right
  252. \define@key {mpr}{flushleft}[]{\mpr@centerfalse}
  253. \define@key {mpr}{center}[]{\mpr@centertrue}
  254. \define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax
  255. \advance \hsize by -\wd0\box0}
  256. \define@key {mpr}{width}{\hsize #1}
  257. \define@key {mpr}{sep}{\def\mpr@sep{#1}}
  258. \define@key {mpr}{before}{#1}
  259. \define@key {mpr}{lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}}
  260. \define@key {mpr}{Lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}}
  261. \define@key {mpr}{narrower}{\hsize #1\hsize}
  262. \define@key {mpr}{leftskip}{\hskip -#1}
  263. \define@key {mpr}{reduce}[]{\let \mpr@fraction \mpr@@reduce}
  264. \define@key {mpr}{rightskip}
  265. {\setbox \mpr@right \hbox {\unhbox \mpr@right \hskip -#1}}
  266. \define@key {mpr}{LEFT}{\setbox0 \hbox {$#1$}\relax
  267. \advance \hsize by -\wd0\box0}
  268. \define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax
  269. \advance \hsize by -\wd0\box0}
  270. \define@key {mpr}{Left}{\llap{$\TirName {#1}\;$}}
  271. \define@key {mpr}{right}
  272. {\setbox0 \hbox {$\;\TirName {#1}$}\relax \advance \hsize by -\wd0
  273. \setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}}
  274. \define@key {mpr}{RIGHT}
  275. {\setbox0 \hbox {$#1$}\relax \advance \hsize by -\wd0
  276. \setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}}
  277. \define@key {mpr}{Right}
  278. {\setbox \mpr@right \hbox {\unhbox \mpr@right \rlap {$\;\TirName {#1}$}}}
  279. \define@key {mpr}{vdots}{\def \mpr@vdots {\@@atop \mpr@vdotfil{#1}}}
  280. \define@key {mpr}{after}{\edef \mpr@after {\mpr@after #1}}
  281. \newdimen \rule@dimen
  282. \newcommand \mpr@inferstar@ [3][]{\setbox0
  283. \hbox {\let \mpr@rulename \mpr@empty \let \mpr@vdots \relax
  284. \setbox \mpr@right \hbox{}%
  285. $\setkeys{mpr}{#1}%
  286. \ifx \mpr@rulename \mpr@empty \mpr@inferrule {#2}{#3}\else
  287. \mpr@inferrule [{\mpr@rulename}]{#2}{#3}\fi
  288. \box \mpr@right \mpr@vdots$}
  289. \setbox1 \hbox {\strut}
  290. \rule@dimen \dp0 \advance \rule@dimen by -\dp1
  291. \raise \rule@dimen \box0}
  292. \def \mpr@infer {\@ifnextchar *{\mpr@inferstar}{\mpr@inferrule}}
  293. \newcommand \mpr@err@skipargs[3][]{}
  294. \def \mpr@inferstar*{\ifmmode
  295. \let \@do \mpr@inferstar@
  296. \else
  297. \let \@do \mpr@err@skipargs
  298. \PackageError {mathpartir}
  299. {\string\inferrule* can only be used in math mode}{}%
  300. \fi \@do}
  301. %%% Exports
  302. % Envirnonment mathpar
  303. \let \inferrule \mpr@infer
  304. % make a short name \infer is not already defined
  305. \@ifundefined {infer}{\let \infer \mpr@infer}{}
  306. \def \tir@name #1{\hbox {\small \sc #1}}
  307. \let \TirName \tir@name
  308. \let \RefTirName \tir@name
  309. %%% Other Exports
  310. % \let \listcons \mpr@cons
  311. % \let \listsnoc \mpr@snoc
  312. % \let \listhead \mpr@head
  313. % \let \listmake \mpr@makelist
  314. \endinput