Closed philher closed 1 month ago
I think the problem is that the number of overlays depends on a test which is performed inside the picture. So when using memos, that test is never performed. What you would need to do would be to restructure things so that the test is performed outside the picture or so that the result of the test is included in the context in a way which tells memoize the number of slides.
But Beamer already provides features allowing you to do this, so it would make more sense, imho, to use those rather than inventing a separate mechanism. You could do this just using overlay specifications and e.g. \againframe
if you create the 7 slides but restrict display to 3 initially and then display the last 4 with \againframe
.
For example,
\begin{filecontents}[overwrite]{tikz_pic.tex}
\begin{tikzpicture}[
/mmz/per overlay,
x=5mm,y=5mm,
executable plans/.style={%
densely dotted, very thick
},
valid plans/.style={%
draw=Green, very thick,
},
decomp plans/.style={%
draw=Blue, very thick,
densely dashed,
},
opt plan/.style={%
draw=black, fill=black,
circle,
inner sep=0pt, minimum size=6pt
},
]
\draw [executable plans,visible on=<1->] (0,0) ellipse (15 and 7);
\draw [valid plans,visible on=<2->] (3,0) ellipse (5 and 3);
\node [opt plan,visible on=<3>] at (1,-1) {};
\draw [decomp plans,visible on=<6->] (-2,0) ellipse (6 and 4);
\node [opt plan,visible on=<7->] at (1,-1) {};
\end{tikzpicture}
\end{filecontents}
\RequirePackage{memoize}
\documentclass[dvipsnames,10pt]{beamer}
\geometry{paperwidth=170.67mm, paperheight=96mm}
\mmzset{prefix=memos/,include context in ccmemo,}
\usepackage{tikz}
\tikzset{
invisible/.style={opacity=0,text opacity=0},
visible on/.style={alt=#1{}{invisible}},
alt/.code args={<#1>#2#3}{%
\alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path
},
}
\begin{document}
\begin{frame}<1-3>[label=7frames]
\frametitle<1-3>{Only 3 overlays}
\frametitle<4-7>{All 4 overlays}
\begin{figure}
\centering
\input{tikz_pic.tex}
\end{figure}
\end{frame}
\againframe<4->{7frames}
\end{document}
produces the expected result and is more aligned with the way Beamer approaches things.
If not, wouldn't you need to make the number of overlays recorded by memoize
depend on (some features of) the context?
What you would need to do would be to restructure things so that the test is performed outside the picture or so that the result of the test is included in the context in a way which tells memoize the number of slides.
I thought the line \mmzset{meaning to context=\nodecomp}
did this in my example ? And indeed, without it, not only is the number of overlay wrong, but also the content of the image becomes the same on all slides.
But Beamer already provides features allowing you to do this, so it would make more sense, imho, to use those rather than inventing a separate mechanism.
I agree that on this simple example, it is clearly better to use the \againframe
mechanism, but in my real use case I would like to be able to change part of the slides and keep the remaining going untouched from this "modified" version, and it is then would make for a quite messy code.
If not, wouldn't you need to make the number of overlays recorded by memoize depend on (some features of) the context?
This is kind of what I wanted to do, but I could not find a way to do this... Looking at the generated .memo files, the (simplified) tikzpicture memo file contains the following code:
\mmzMemo
\global \mmzContextExtra {overlay=\csname beamer@overlaynumber\endcsname , pauses=\ifmemoizing \mmzBeamerPauses \else \expandafter \the \csname c@beamerpauses\endcsname \fi ,}%
\mmzSetBeamerOverlays {1}{4}%
\mmzSource
\begin {tikzpicture} <...> {tikzpicture}
I guess the issue lies in the line \mmzSetBeamerOverlays {1}{4}%
being set identically for every context, but I do not know how (if possible), this might be moved to the 'context part' of the memo ?
New testing also shows that forcing the overlay number manually using begin{frame}<1-X>
for the broken slide (or even both) produces the correct output when using memoize, which supports this previous idea.
I have looked at the Beamer support section in the manual, but I could not understand well enough to go beyond these ideas...
Sorry, I'm a bit swamped here, but I'll try to look into it asap.
On a cursory look, @cfr42's analysis is correct. The number of overlays is stored in the c-memo, which is the same for all contexts and thus for both frames.
One idea could be to use prefix
, as we did for the modes in #16. Another idea is to implement the possibility of salting the code hash.
In fact, I'm now thinking that my implementation of context
is flawed. I'm considering a change, whereas the context set prior to invoking memoization would impact the code hash, and only the context set during the memoization would determine what is now the context hash. I believe this would fix the issue, but I have to mull it over for a bit. Btw, I believe the change would be entirely internal, i.e. there would be change in the UI.
I have implemented salt
, the OPs issue now seems to be resolved. Please see the new docs (prerelease 1.4.0-wip) for what it does (and tell me whether it is comprehensible).
In my previous post, I actually considered having outside-memoization context
behave like salt
, but I realized this would not work with the current Beamer support code, because it would create a separate c-memo for each overlay. With salt, it is each frame which receives a separate c-memo, which is perfect, as c-memo is where Memoize stored the number of overlays required.
Incidentally, salt
could also handle Beamer modes, but I would rather stick with the current setup of different prefix
es, because these facilitate clean-up.
I have implemented
salt
, the OPs issue now seems to be resolved. Please see the new docs (prerelease 1.4.0-wip) for what it does (and tell me whether it is comprehensible).
Where is the right place to comment on this?
I can't build the current version:
! Package Listings Error: File `examples/titlepage.tex.c1.listing(.tex)' not fo
und.
Type X to quit or <RETURN> to proceed,
or enter new name. (Default extension: tex)
Enter file name:
! Undefined control sequence.
\\lst@inputlisting ...empty }\egroup \lst@doendpe
\@newlistfalse \ignorespaces
l.201 }
?
! error: (pdf backend): cannot open file for embedding
! ==> Fatal error occurred, no output PDF file produced!Latexmk: Getting log file 'memoize-doc.log'
Latexmk: Examining 'memoize-doc.fls'
Latexmk: Examining 'memoize-doc.log'
Latexmk: Index file 'memoize-doc.idx' was written
Have index file 'memoize-doc.idx', memoize-doc.ind memoize-doc
Latexmk: Errors, so I did not complete making targets
Collected error summary (may duplicate other messages):
lualatex: Command for 'lualatex' gave return code 1
Refer to 'memoize-doc.log' and/or above output for details
Latexmk: Undoing directory change
Latexmk: Sometimes, the -f option can be used to get latexmk
to try to force complete processing.
But normally, you will need to correct the file(s) that caused the
error, and then rerun latexmk.
In some cases, it is best to clean out generated files before rerunning
latexmk after you've corrected the files.
make: *** [Makefile:101: doc/memoize-doc.pdf] Error 12
This is running
TEXMFHOME=. make
from the top-level directory. (I just realised I should probably export TEXMFHOME but I don't think my memoize.cfg
is responsible here.)
[I guess the Makefile doesn't include shell escape yet?]
After editing the Makefile, things go better, but I still get an error:
! You can't use `macro parameter character #' in horizontal mode.
<argument> GitHub issue ##
27
l.1716 % issue #27}
.
? h
Sorry, but I'm not programmed to handle this case;
I'll just pretend that you didn't ask for it.
If you're in the wrong mode, you might be able to
return to the right one by typing `I}' or `I$' or `I\par'.
I've noticed that if you use conditional compilation (with
\ifdefined
) which changes the content of a picture, the output is wrong (in the number of overlays) if you typeset this picture on multiple frames.If the picture is generated twice with the different overlay count on two frames, the last one fixes the number of overlay for both of them. Content is correct on the displayed overlays (potentially cut/repeated to accomodate fewer/more overlays)
Disabling memoize (simply locally for this problematic picture) works and gives the expected output, so the workaround is simple for a rather niche case, but it would be great if it could be made work! Maybe I have made a mistake with the
per overlay
usage? If so let me know.I have only tested it with beamer, using the latest version of the packages on CTAN (1.3.0), compiling using latexmk:
latexmk -shell-escape -lualatex main.tex
MWE
The first slide should have 3 overlays but has 4. Reversing the frame order shows the opposite behaviour: the 4 overlay frame only gets 3. ```latex \RequirePackage{memoize} \documentclass[dvipsnames,10pt]{beamer} \geometry{paperwidth=170.67mm, paperheight=96mm} \usepackage{tikz} \tikzset{ invisible/.style={opacity=0,text opacity=0}, visible on/.style={alt=#1{}{invisible}}, alt/.code args={<#1>#2#3}{% \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path }, } \begin{filecontents}[overwrite]{tikz_pic.tex} \mmzset{meaning to context=\nodecomp} % \mmzset{disable} % Conditional compilation which changes the number of overlays appears broken \begin{tikzpicture}[ /mmz/per overlay, x=5mm,y=5mm] \tikzstyle{executable plans}=[ densely dotted, very thick ] \tikzstyle{valid plans}=[ draw=Green, very thick, ] \tikzstyle{decomp plans}=[ draw=Blue, very thick, densely dashed, ] \tikzstyle{opt plan}=[ draw=black, fill=black, circle, inner sep=0pt, minimum size=6pt ] \ifdefined\nodecomp \draw [executable plans,visible on=<1->] (0,0) ellipse (15 and 7); \draw [valid plans,visible on=<2->] (3,0) ellipse (5 and 3); \node [opt plan,visible on=<3->] at (1,-1) {}; \else \draw [executable plans,visible on=<1->] (0,0) ellipse (15 and 7); \draw [valid plans,visible on=<2->] (3,0) ellipse (5 and 3); \draw [decomp plans,visible on=<3->] (-2,0) ellipse (6 and 4); \node [opt plan,visible on=<4->] at (1,-1) {}; \fi \end{tikzpicture} \end{filecontents} \begin{document} \begin{frame} \frametitle{Only 3 overlays} \newcommand{\nodecomp}{}% Remove part of the figure \begin{figure} \centering \input{tikz_pic.tex} \end{figure} \end{frame} \begin{frame} \frametitle{All 4 overlays} \begin{figure} \centering \input{tikz_pic.tex} \end{figure} \end{frame} \end{document} ```