\NeedsTeXFormat{LaTeX2e} \ProvidesPackage{shadethm}[1999/11/23] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % ShadeThm.sty % Shaded theorem environments in LaTeX, with \newshadetheorem in addition to % \newtheorem. % % USAGE % Used as a LaTeX2e style, with \usepackage{shadethm}, it allows declarations % of the form \newshadetheorem{theorem}{Theorem}, so that % \begin{theorem} $e=mc^2$ \end{theorem} % will produce the usual theorem, only placed in a shaded box. % Options. Two come in this file: % bodymargin (default) The body of the shaded text lines up with the % margins. Just as though you called newtheorem, then colored later. % Shading falls outside the margin. % shademargin The shading lines up with the margins, so the body of % shaded text comes out a little thinner. % If you call it with an option not on that list then it will look for a % file .sth and take the parameters from there. See the included % files shadein.sth and colored.sth, the first of which gives theorems that are % (like LaTeX quotations) indented left and right and the second of which % gives color shading. % % REMARKS % (1) You can of course have non-shaded environments, also. The \newtheorem % command still works. % (2) Numbering within: An prior version of this style required that you % number within like this: % \newshadetheorem{thm}{Theorem} % \newshadetheorem{note}[shadethm]{Note} % No longer needed! % but this one drops that requirement. If you didn't use the old version, % forget about it. % (3) Uses the graphics package. Look for it in the CTAN TeX-archive nearest % you, for instance at tug.ctan.org. % (4) Works with amsthm.sty. % (5) Notice that if you say \newshadetheorem{theorem}{Theorem} and then % \newtheorem{theorem}{Theorem} then you will get an error message since % the first allows you to say \begin{theorem} ..., as does the second. % % INSTALLATION % Put this where your TeX looks for .sty files. % There are some parameters you could set the default for (try them as is, % first). % (i) shadethmcolor The shading color of the background. See the % documentation for the color package, but with a `gray' model, I find .97 % looks good out of my printer, while a darker shade like .92 is needed % to make it copy well. (Black is 0, white is 1.) % (i*) shaderulecolor The shading color of the border of the shaded box. % See (i). If \shadeboxrule is set to 0pt then this won't print anyway. % (i**) shadeboxrule The width of the border around the shading. Set it to % 0pt (not just 0) to make it disappear. % (i***) shadeboxsep The length by which the shade box surrounds the text. % (ii) shadesetinsideminipage The theorems are set inside a minipage to % get line breaks, but some things, like paragraph indents, are messed % with there, so I have a hook to reset them. Probably you can just % leave this alone. % (iii) The default option. Change the \ExecuteOptions{...} right before % the \ProcessOptions. % Comment: % If you get an error about `undefined color model' then you need to create % the file color.cfg in the same place as color.sty, and put in it the line % \ExecuteOptions{dvips} (or whatever is the name of your driver). See the % documentation for the graphics package. I needed this in the distant past % under NTeX. % % BUGS % (1) Page breaks are a problem since it sets the theorem before it is shaded. % The theorem is put into a minipage in order to have the right line breaks % put in, but then can't be broken across pages. I'd be interested in any % fixes for this. DA? % % LICENSE %% Copyright 1999 Jim Hefferon jim@joshua.smcvt.edu % This program can redistributed and/or modified under the terms % of the LaTeX Project Public License Distributed from CTAN % archives in directory macros/latex/base/lppl.txt; either % version 1 of the License, or (at your option) any later version. % % HISTORY % 99XI23 jh Redid the parsing to stick to \newcommand-style calls. Needed % to put in some oppresive \expandafter strings. % 99VII09 jh tex@joshua.smcvt.edu Fixed the number within situation. LPPL % added. % 97I07 jh Changed the interior of the \DeclareOptions to \AtBeginDocument % for cases where the \textwidth is changed. % 95VI19 jh Adapted for LaTeX2e. Now uses the graphics package, and all % the neat 2e package stuff. Still haven't rewritten the parsing code to % use the new optional arguments to \newcommand, though. Ah well. % 94VII11 jim hefferon hefferon@smcvax.smcvt.edu. First written (after lots % of sporadic tries, over months; I couldn't get any of the extant shading % macros to work with theorems) from a hint in TvZ's Fancybox writeup. % It's all so easy once you know how. % \DeclareOption{bodymargin}{ \AtEndOfPackage{% \setlength{\shadeboxsep}{2pt} \setlength{\shadeboxrule}{0pt} \setlength{\shadedtextwidth}{\textwidth} \setlength{\shadeleftshift}{-\shadeboxsep} \setlength{\shaderightshift}{-\shadeboxsep} \definecolor{shadethmcolor}{gray}{0.92} \definecolor{shaderulecolor}{gray}{0.92} } } \DeclareOption{shademargin}{ \AtEndOfPackage{% \setlength{\shadeboxsep}{2pt} \setlength{\shadeboxrule}{0pt} \setlength{\shadedtextwidth}{\textwidth} \addtolength{\shadedtextwidth}{-2\shadeboxsep} \setlength{\shadeleftshift}{0pt} \setlength{\shaderightshift}{0pt} \definecolor{shadethmcolor}{gray}{0.92} \definecolor{shaderulecolor}{gray}{0.92} } } \DeclareOption*{\InputIfFileExists{\CurrentOption.sth}{}{% \typeout{shadethm warning: option \CurrentOption\space not known.}}} \ExecuteOptions{bodymargin} %default \ProcessOptions \RequirePackage{color} % Save the document paragraph indents so they can be reasserted inside the % minipage into which the theorems get put. \newlength{\saveparindent} %to have paragraphs default to their \setlength{\saveparindent}{\parindent} %usual indent inside the minipage \newcommand{\shadesetinsideminipage}{% %To reset this inside an option, \setlength{\parindent}{\saveparindent}} %or a document, \renewcommand{...} % Declare the lengths we need. Set in the package options. % Here is a diagram: % text text text text text text text text text text text text % ------------------------------------------------------ % | Theorem. My bonnie lies over the ocean. My bonnie | % | lies over the sea. | % ------------------------------------------------------ % --->| |<---- --->| |<-- % \shadeleftshift \shadeboxsep % (all four sides) % % |<-------------- \shadetextwidth ---------------->| % \newlength{\shadeboxsep} %start of color to start of text; four sides \newlength{\shadeboxrule} %width of bordering rule \newlength{\shadedtextwidth} %width of the text body \newlength{\shadeleftshift} %margin to start of shading (may be negative) \newlength{\shaderightshift} %makes total line width come out (may be negative) % MAIN CODE % see LaTeXbook (second edition) pp 108 and 132 % (1) make a box \saveshadebox that will hold the text that is to be % typeset in the theorem. % (2) Read that material in with the lrbox environment. The material % is set in a minipage so the margins are controllable. % (3) Use that box, inside of an fcolorbox. % Notes % * lrbox is used instead of savebox because this is an environment. % * The fcolorbox is inside a trivlist because that makes the vertical % spacing come out right. I don't know how else to do it. % * The fcolorbox is left shifted by some length (which may be negative) and % then aftward, a right shift is put in. \newsavebox{\shadesavebox} % no `@'; users can redefine shadebox if they want \newenvironment{shadebox}% % shadow boxes or something. {\begin{lrbox}{\shadesavebox}\begin{minipage}{\shadedtextwidth}% \shadesetinsideminipage}% {\end{minipage}\end{lrbox}% \begin{trivlist}\item[]% In a trivlist because theorems are in trivlists. \setlength{\fboxsep}{\shadeboxsep}% \setlength{\fboxrule}{\shadeboxrule}% \mbox{\hspace{\shadeleftshift}\fcolorbox{shaderulecolor}{shadethmcolor}{\usebox{\shadesavebox}}\hspace{\shaderightshift}}% \end{trivlist}} %PARSING CODE % The definition of \newshadetheorem is modelled on the one for \newtheorem % in latex.tex. % The invocation possibilities are: % \newshadetheorem{NAME}{TEXT}[COUNTER] % e.g., \newshadetheorem{theorem}{Theorem}[section] meaning to allow % one to say \begin{theorem} $e=mc^2$ \end{theorem} to produce % Theorem 1.1.1 e=mc2 % shaded and numbered by section. % \newshadetheorem{NAME}[OLDNAME]{TEXT} % e.g., \newshadetheorem{remark}[theorem]{Remark} meaning to allow % one to say \begin{remark} Obvious. \end{remark} to produce % Remark 1.1.2 Obvious. % shaded and numbered with the same counter used for theorems. % \newcommand parsing % In LaTeX2e, to call a macro with an optional argument, let the % optional's default value be given in a second set of []'s: % \newcommand{\mymac}[2][hello]{#2, ``#1''} will have % \mymac{I say} |---> I say ``hello'' % \mymac[goodbye]{You say} |---> You say ``goodbye'' % I want to use this to parse LaTeX's % \newtheorem{--env_name--}{--caption--}[--within--] % or \newtheorem{--env_name--}[--numbered_like--]{--caption--} % So % (1) \newshadetheorem{arg1} % arg1: the environment name (e.g. definition) % It ends by calling a macro \sth@getcaption with one mandatory argument and % one optional argument. % (2) \sth@getcaption[oparg1]{arg1} % arg1: the caption name (e.g. Definition) % oparg1: the numbered_like (e.g., theorem) % It ends by calling a macro \sth@getwithin of no mandatory arguments but % one optional argument. % (3) \sth@getwithin[oparg1] % oparg1: the numbered within (e.g. subsection) % This routine finishes the processing. Depending on the four possibilities % of whether there is a numbered_like or not, and whether there is a % within or not, \newtheorem is called as is appropriate. % If there is no numbered_like, then the counter has to be set. That is, % a user expects to say \newtheorem{corollary}[theorem]{Corollary} and get % a corollary environment that is numbered in the same sequence as the % theorem environment, e.g., uses the theorem counter c@theorem. But in % runnning the \newshadetheorem we have called a \newtheorem{shadetheorem}... % and so the counter actually created is c@shadetheorem. We need the three % c@theorem, p@theorem and \thetheorem. % **** Remark on the \expandafter madness **** % Probably I am going about this all wrong ... % The construct % \newtheorem{\sth@envname}{\sth@caption} % doesn't do the job here because the \sth@envname and sth@caption aren't % resolved until they are called in the document: % after \newshadetheorem{theorem}{Theorem} % \newshadetheorem{corollary}{Corollary} % and later in the document % \begin{theorem} .. \end{theorem} % we get ``Corollary'' because that's what \sth@envname is at that moment. % Aarrg! % Instead, it has to be expanded when \newshadetheorem is called. This is % hard, IMHO. \expandafter<\tok2> puts on a stack and expands % . If is another \expandafter then we have % \expandafter\expandafter which resolves to % . If is another \expandafter then % there is another round of expansion. % * To have \newshadetheorem{thm}{Thm} expand, we do this (where \ea is an % abbreviation for \expandafter): % \ea\ea\ea\newtheorem\ea\ea\ea{\ea\sth@shadeenvname\ea}\ea{\sth@caption} % ... which resolves to ... % \ea \newtheorem \ea { \sth@shadeenvname } {Thm } % ... which in turn resolves to ... % \newtheorem { thm } {Thm } % ... which is what I want. % * To have a three-argument case come out right, we need seven \ea's. % Consider the one that we want to come out as \newtheorem{thm}{Thm}[section]. % \ea\ea\ea\ea\ea\ea\ea\newtheorem\ea\ea\ea\ea\ea\ea\ea{ % \ea\ea\ea\sth@shadeenvname\ea\ea\ea} % \ea\sth@caption\ea}\ea[\sth@within] % (ignore the line breaks, which are for visual clarity only) % ... which resolves to ... % \ea \ea \ea \newtheorem \ea \ea \ea { % \ea \sth@shadeenvname \ea } % \sth@caption } [section ] % ... which in turn resolves to ... % \ea \newtheorem \ea { % \sth@shadeenvname } % Thm } [section ] % ... which, in its turn, resolves to ... % \newtheorem { % shadethm } % Thm } [section ] % which is the call that I want. % TeX is a strange place. \newcommand{\newshadetheorem}[1]{% \def\sth@envname{#1}\def\sth@shadeenvname{shade#1}% \sth@getcaption} \newcommand{\sth@getcaption}[2][\relax]{% \def\sth@caption{#2}\def\sth@numberedlike{#1}% \sth@getwithin} \newcommand{\sth@getwithin}[1][\relax]{% \def\sth@within{#1}% \if\sth@numberedlike\relax %if --numbered_like-- is not present \if\sth@within\relax %\newtheorem{shade\sth@envname}{\sth@caption}% \expandafter\expandafter\expandafter\newtheorem\expandafter\expandafter\expandafter{\expandafter\sth@shadeenvname\expandafter}\expandafter{\sth@caption} % \else %\newtheorem{shade\sth@envname}{\sth@caption}[\sth@within]% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\newtheorem\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\sth@shadeenvname\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter{\expandafter\sth@caption\expandafter}\expandafter[\sth@within]% \fi \global\expandafter\countdef\csname \expandafter c\expandafter @\sth@envname\endcsname=\allocationnumber % just allocated shade; make be the same register \expandafter\expandafter\expandafter\gdef\expandafter\csname the\sth@envname\expandafter\endcsname\expandafter{\csname theshade\sth@envname\endcsname}% make \the display the same as \theshade \global\expandafter\let\csname p@\sth@envname\endcsname\@empty % and what the heck is p@, anyway? \else %if --numbered_like-- is present \if\sth@within\relax %\newtheorem{shade\sth@envname}[\sth@numberedlike]{\sth@caption}% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\newtheorem\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter\sth@shadeenvname\expandafter\expandafter\expandafter}\expandafter\expandafter\expandafter[\expandafter\sth@numberedlike\expandafter]\expandafter{\sth@caption}% \else % Presumably get an error from newtheorem. \typeout{!!!ERROR, shadethm.sty: \newshadetheorem used with both [numbered like] and [within] options.} \newtheorem{\sth@shadeenvname}[\sth@numberedlike]{\sth@caption}[\sth@within]% \fi \fi \expandafter\shade@@thm\expandafter{\sth@envname}} % \shade@@thm % arg1: name of environment (e.g., `definition') % Define an environment that will be called by the user (e.g., % \begin{definition} .. \end{definition}. % Calls, e.g., \begin{shadedefinition} .. \end{shadedefinition} inside of % a \begin{shadebox} .. \end{shadebox} environment. \def\shade@@thm#1{% \newenvironment{#1}% {\begin{shadebox}\begin{shade#1}}% {\end{shade#1}\end{shadebox}}} \endinput %end shadethm.sty =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-shadetest.tex-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- \documentclass{article} % test of LaTeX package shadethm.sty \usepackage{shadethm} \newshadetheorem{theorem}{Theorem}[section] \newshadetheorem{cor}[theorem]{Corollary} \newtheorem{remark}[theorem]{Remark} \newtheorem{unshadedtheorem}[theorem]{Theorem} \newtheorem{comment}{Comment}[section] \begin{document} Document begins with some initial text. \section{First Section} Here is some initial text before the shaded box. \begin{theorem} This is the text to be shaded. \end{theorem} This is some text after the first shade. It is separated from the environments by a blank line; that is all handled as usual in \LaTeX. \begin{cor} This is more text to be shaded. It is numbered with the same counter as the environment above. Multiple paragraphs will be handled with the usual paragraph indentation, unless of course the user asks for a different paragraph indentation inside the environment. \end{cor} This is not separated from the prior environment by a blank line and so I don't expect a new paragraph. This shows that the default is for the shaded areas have the usual text size so that shading sticks out into the margin. This is the shadethm option \emph{bodymargin}. The behavior of having the shading end at the margin (so the words do not take up the full text width) comes from the option \emph{shademargin}, invoked with \verb!\usepackage[shademargin]{shadethm}!. \begin{unshadedtheorem} More text. This time not set in shade, but it is still numbered in the same sequence. \end{unshadedtheorem} A bit more. \begin{comment} More text. This time neither set in shade, nor numbered in the same sequence. \end{comment} \section{A New Section} Section preamble. \begin{theorem} This theorem is shaded and the number has been reset by the section. \end{theorem} \begin{remark} And a closing remark \end{remark} Finishing text. \clearpage \section{A Test of Colors} This section shows how you can fool around to see some of you own colors. % Set up some lengths so that you can see the border. \setlength{\shadeboxsep}{2pt} \setlength{\shadeboxrule}{.4pt} \setlength{\shadedtextwidth}{\textwidth} \addtolength{\shadedtextwidth}{-2\shadeboxsep} \addtolength{\shadedtextwidth}{-2\shadeboxrule} \setlength{\shadeleftshift}{0pt} \setlength{\shaderightshift}{0pt} % Macro to test colors \newcommand{\thmwithcmykcolor}[2]{% \par Material before the theorem. \definecolor{shadethmcolor}{cmyk}{#1}% \definecolor{shaderulecolor}{cmyk}{#2}% \begin{theorem} This is a theorem set in the cmyk color \textbf{#1}, surrounded with a borderline set in the cmyk color \textbf{#2}. Note, for instance, that shades darken on overheads, so test your colors where you will use them. \end{theorem}} % Some colors \thmwithcmykcolor{.10,.10,0,0}{.75,.75,0,.5} \thmwithcmykcolor{.04,.04,0,.10}{.99,0,0.52,0.70} \thmwithcmykcolor{0,.13,.11,0}{0,0.88,0.85,0.35} The prior theorem illustrates what happens if you use the option \emph{colored}, as supplied in the file \verb!colored.sth!, except that the supplied file has the color stick out into the margin. One more supplied option is \emph{shadein} where each shaded theorem is indented, like a \LaTeX\ quotation. % ---> Uncomment if you want to test dvips's named colors % \newcommand{\thmwithnamedcolor}[1]{% % \par Material before the theorem. % \definecolor{shadethmcolor}{named}{#1}% % \definecolor{shaderulecolor}{named}{Black}% % \begin{theorem} % This is a theorem set in the named color \textbf{#1}, surrounded with a blac % borderline. % Note, for instance, that colors darken on overheads, so test your colors % where you will use them. % \end{theorem}} % % These are all the DVIPS named colors from color.pro (as of 1999-Aug-11). % \thmwithnamedcolor{GreenYellow} % \thmwithnamedcolor{Yellow} % \thmwithnamedcolor{Goldenrod} % \thmwithnamedcolor{Dandelion} % \thmwithnamedcolor{Apricot} % \thmwithnamedcolor{Peach} % \thmwithnamedcolor{Melon} % \thmwithnamedcolor{YellowOrange} % \thmwithnamedcolor{Orange} % \thmwithnamedcolor{BurntOrange} % \thmwithnamedcolor{Bittersweet} % \thmwithnamedcolor{RedOrange} % \thmwithnamedcolor{Mahogany} % \thmwithnamedcolor{Maroon} % \thmwithnamedcolor{BrickRed} % \thmwithnamedcolor{Red} % \thmwithnamedcolor{OrangeRed} % \thmwithnamedcolor{RubineRed} % \thmwithnamedcolor{WildStrawberry} % \thmwithnamedcolor{Salmon} % \thmwithnamedcolor{CarnationPink} % \thmwithnamedcolor{Magenta} % \thmwithnamedcolor{RedViolet} % \thmwithnamedcolor{Fuchsia} % \thmwithnamedcolor{Lavender} % \thmwithnamedcolor{Thistle} % \thmwithnamedcolor{Orchid} % \thmwithnamedcolor{DarkOrchid} % \thmwithnamedcolor{Purple} % \thmwithnamedcolor{Plum} % \thmwithnamedcolor{Violet} % \thmwithnamedcolor{RoyalPurple} % \thmwithnamedcolor{BlueViolet} % \thmwithnamedcolor{Periwinkle} % \thmwithnamedcolor{CadetBlue} % \thmwithnamedcolor{CornflowerBlue} % \thmwithnamedcolor{MidnightBlue} % \thmwithnamedcolor{NavyBlue} % \thmwithnamedcolor{RoyalBlue} % \thmwithnamedcolor{Blue} % \thmwithnamedcolor{Cerulean} % \thmwithnamedcolor{Cyan} % \thmwithnamedcolor{ProcessBlue} % \thmwithnamedcolor{SkyBlue} % \thmwithnamedcolor{Turquoise} % \thmwithnamedcolor{TealBlue} % \thmwithnamedcolor{Aquamarine} % \thmwithnamedcolor{BlueGreen} % \thmwithnamedcolor{Emerald} % \thmwithnamedcolor{JungleGreen} % \thmwithnamedcolor{SeaGreen} % \thmwithnamedcolor{Green} % \thmwithnamedcolor{ForestGreen} % \thmwithnamedcolor{PineGreen} % \thmwithnamedcolor{LimeGreen} % \thmwithnamedcolor{YellowGreen} % \thmwithnamedcolor{SpringGreen} % \thmwithnamedcolor{OliveGreen} % \thmwithnamedcolor{RawSienna} % \thmwithnamedcolor{Sepia} % \thmwithnamedcolor{Brown} % \thmwithnamedcolor{Gray} Enjoy! \textit{--Jim Hefferon} \end{document}