Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Sorry, it's me again. Gonzalo has hinted me to the very nice leftbar environment in the framed package, which I now use for definitions, theorems and similar environment. Now I've got a new problem: Footnotes (\footnote) from inside the leftbar environment are not shown! The label is there, but there is no footnote with the corresponding number.

According to this here and similar sources, this can be fixed by using \footnotemark and \footnotetext. The problem is: I'm using SWP and would like to have the \footnote command for footnotes. I thought of something like this:

\renewcommand{\footnote}[1]{\footnotemark \footnotetext{#1}}

But \footnotemark and \footnotetext need a label. So what I would like the most is someting like

\renewcommand{\footnote}[1]{\footnotemark[some arbitrary string "x" that cannot collide with an "x" from a different footnotemark] \footnotetext["x"]{#1}}

I've tried to use #1 itself as "x", but this spits out errors (not surprisingly, given that it is non-sanitized LaTeX). Is there a trick here, or is my syntax wrong?

EDIT: My renewcommand is stupid anyway. The trick is to have the \footnotetext come after the end of the leftbar environment. Is there a way to get this through renewcommand?

share|improve this question
add comment

2 Answers 2

up vote 5 down vote accepted

A slightly longer code, which allows you to only type \footnote. The idea is to make each footnote append \footnotetext{#1} to a token list. This token list is then typeset at the right place. Some trickery is required to get nesting right, as well as hyperref support. Normally, this can be used for other (non-verbatim-ish) environments.

Comments in the code.

\documentclass{article}
\usepackage{etoolbox} % for "\pretocmd".
\makeatletter
%
% User command, see the end of the preamble for use.
% We redefine the environment by adding "\savefoot@begin" at 
% the beginning, and "\savefoot@end" at the end.
%
\newcommand{\DeclareSavefootEnvironment}[1]{%
  \expandafter\pretocmd\csname #1\endcsname
              {\savefoot@begin}{}{\savefoot@patch@error{#1}}%
  \expandafter\pretocmd\csname end#1\endcsname
              {\savefoot@end}{}{\savefoot@patch@error{#1}}%
}
\newcommand{\savefoot@patch@error}[1]{%
  \PackageError{savefoot}{etoolbox failed to patch the environment #1, sorry}{}}
%
% Register allocation.
%
\newcount\c@savefoot@depth
\newtoks\savefoot@toks
%
% "\savefoot@begin" starts an environment which saves footnotes.
% We only want to output footnotes outside any such environment,
% so we count how deep we are in this kind of environment using
% the count "\c@savefoot@depth", which pretends to be a LaTeX
% counter. 
%
% We will store all the "\footnotetext" into the toks 
% "\savefoot@toks". This is initialized _locally_ at the start
% of each "savefoot" environment.
% 
\newcommand{\savefoot@begin}{%
  \advance\c@savefoot@depth by 1\relax  
  \savefoot@toks={}}
%
% When ending a savefoot environment, we check if it was the 
% outermost one. In that case, "\@secondoftwo", we output the
% "\footnotetext" that we saved, after the end of the group.
% The "\endgroup" must be explicitly there; this is the case
% because of how "\end{...}" works in LaTeX2e.
% 
% Since the register "\savefoot@toks" is restored at the end 
% of the group, we need to expand it inside the group, then 
% send "\savefoot@append{<expanded \savefoot@toks>}" after the
% "\endgroup", hence the "\expandafter"s. Same thing when we 
% need to typeset.
% 
\newcommand{\savefoot@end}{%
  \ifnum\c@savefoot@depth>\@ne
  \expandafter\@firstoftwo
  \else
  \expandafter\@secondoftwo
  \fi
  {% Nested, don't output, save to the level above.
    \expandafter\do@after@explicit@endgroup\expandafter{%
      \expandafter\savefoot@append\expandafter{\the\savefoot@toks}}%
  }%
  {% Outside, output.
    \expandafter\do@after@explicit@endgroup\expandafter{%
      \the\savefoot@toks}%
  }%
}
%
% Appending to a toks is standard.
%
\newcommand{\savefoot@append}[1]{%
  \savefoot@toks\expandafter{\the\savefoot@toks#1}}%
%
% To put after "\endgroup", we need delimited parameters,
% hence the "\def". We first check that the command is new,
% just in case.
% 
\newcommand{\do@after@explicit@endgroup}{}
\def\do@after@explicit@endgroup#1#2\endgroup{#2\endgroup#1}
%
% Now the footnote command. We save the old definition, 
% used in the case where we are outside any savefoot
% environment. If we are inside a savefoot environment,
% place the "\footnotemark", and append 
% 
%    \savefoot@setcounter{<explicit number>}\footnotetext{<text>}
% 
% to our register. This will be typeset at the end. We cannot
% just do "\footnotetext[<explicit number>]{<text>}", because
% the hyperref package does not like that.
% 
\let\savefoot@old@footnote\footnote
\renewcommand{\footnote}[1]{%
  \ifnum\c@savefoot@depth>\z@
  \expandafter\@firstoftwo
  \else
  \expandafter\@secondoftwo
  \fi
  {% Inside a leftbar, save the text in the relevant toks.
    \footnotemark
    \savefoot@toks=\expandafter{%
      \the\expandafter\savefoot@toks
      \expandafter\savefoot@setcounter\expandafter{\the\c@footnote}%
      \footnotetext{#1}%
    }%
  }%
  {% Don't save, just typeset.
    \savefoot@old@footnote{#1}%
  }%
}
%
% When not using hyperref, just give the counter "footnote" 
% the right value (in that case, "\savefoot@hhyperref@support{#1}"
% will be defined to do nothing).
% 
\newcommand{\savefoot@setcounter}[1]{%
  \setcounter{footnote}{#1}%
  \savefoot@hyperref@support{#1}%
}
% 
% Getting "\footnotetext" and "\footnotemark" to work with hyperref
% is non-trivial, and I probably did something wrong. But at first
% sight it seems ok.
%
\newcommand{\savefoot@hyperref@support}[1]{%
  \setcounter{Hfootnote}{#1}%
  \global \let \Hy@saved@currentHlabel \@currentHlabel 
  \global \let \Hy@saved@currentHref \@currentHref 
  \hyper@makecurrent {Hfootnote}%
  \global \let \Hy@footnote@currentHlabel \@currentHlabel 
  \global \let \Hy@footnote@currentHref \@currentHref 
  \global \let \@currentHlabel \Hy@saved@currentHlabel 
  \global \let \@currentHref \Hy@saved@currentHref
}
%
% If hyperref is not loaded, we disable the hyperref support.
% We check at the "\begin{document}".
%   
\AtBeginDocument{%
  \@ifpackageloaded{hyperref}{}{\let\savefoot@hyperref@support\@gobble}%
}
\makeatother


% ============= Example =====================

\usepackage{framed}
\usepackage{hyperref}
\DeclareSavefootEnvironment{leftbar}

\begin{document}

Some text,\footnote{With a normal footnote.} in which 
footnotes are preserved.\footnote{Even when you put several 
  in a row.}\footnote{Like this.}

\begin{leftbar}
  Also true for the leftbar environment.\footnote{The relevant 
    commands are placed after the end of the environment.} 
  \begin{leftbar}
    And we check that nesting works.\footnote{That was the tricky part\ldots}
  \end{leftbar}
  Maybe it breaks after nesting?\footnote{Let's see.}
\end{leftbar} 

More footnotes.\footnote{Like this.}\footnote{And that.}

\begin{leftbar}
  And another leftbar environment to be sure.\footnote{Does it 
    work? I'll see soon, when I compile.}
\end{leftbar}

\end{document}
share|improve this answer
    
Really nice solution. Chapeau! –  Gonzalo Medina Apr 6 '11 at 23:48
1  
@Gonzalo: thanks. I read a bit more, and found out that the footnote package does it differently, using boxes. And that's much better indeed than my solution, since some macros which were defined when the footnote was issued may not be defined anymore when I typeset it. So really, a better solution if hyperref is not required is: \usepackage{footnote}\makesavenoteenv{leftbar}. –  Bruno Le Floch Apr 7 '11 at 0:17
    
Oh, well, I can't figure out how to make hyperref work with the boxes approach. –  Bruno Le Floch Apr 7 '11 at 0:37
    
Thank you a big deal, already for the reference to the "footnote" package! (I don't use hyperref and don't really plan to.) –  darij grinberg Apr 7 '11 at 9:08
add comment

You can use the manyfoot package; a little example:

\documentclass{article}
\usepackage{manyfoot}
\usepackage{framed}

\DeclareNewFootnote{B}
\begin{document}
text text\footnote{a standard footnote.}
\begin{leftbar}
text text\FootnoteB{*}{text}
\end{leftbar} 
\FootnotetextB{*}{a footnote with a manual mark.}
\end{document}

The package documentation explains all the options that the package gives you to customize the footnotes.

share|improve this answer
    
Thanks, but this still doesn't look macro-izable. I still have to write \FootnotetextB after \end{leftbar}... –  darij grinberg Mar 29 '11 at 13:14
    
@darij grinberg: Then I misunderstood your question; I thought that you wanted to have different markers for the footnotes inside leftbar, but what you want is to have a single command to typeset footnotes inside the leftbar environment, is that correct? –  Gonzalo Medina Mar 29 '11 at 13:22
    
Yep. I am seeing that a package called "bigfoot" (which seems to be a development upon your "manyfoot") offers robust footnotes - can you tell me whether this will help me? Also, how do I install a package without a .sty file? Thanks very much! –  darij grinberg Mar 29 '11 at 13:26
    
@darij grinberg: I am afraid that none of those packages will make the standard \footnote command work inside leftbar; as far as I know the only option is to use \footnotemark, \footnotetext or some variation, like the one I described in my answer. What package do you want to install without a .sty file? –  Gonzalo Medina Mar 29 '11 at 13:53
    
bigfoot. The Ctan site ( ctan.org/tex-archive/macros/latex/contrib/bigfoot ) only gives .ins and .dtx. –  darij grinberg Mar 29 '11 at 14:17
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.