Reset stored values at pagebreaks and environment boundariesHow to properly use DeclareOption within a...
What is the offset in a seaplane's hull?
How is the claim "I am in New York only if I am in America" the same as "If I am in New York, then I am in America?
Why has Russell's definition of numbers using equivalence classes been finally abandonned? ( If it has actually been abandonned).
How to get the available space of $HOME as a variable in shell scripting?
Dragon forelimb placement
How can I hide my bitcoin transactions to protect anonymity from others?
Shell script not opening as desktop application
Can an x86 CPU running in real mode be considered to be basically an 8086 CPU?
Is the month field really deprecated?
What is the command to reset a PC without deleting any files
Why did the Germans forbid the possession of pet pigeons in Rostov-on-Don in 1941?
What do you call a Matrix-like slowdown and camera movement effect?
Do Phineas and Ferb ever actually get busted in real time?
Why don't electron-positron collisions release infinite energy?
Can I make popcorn with any corn?
Python: Add Submenu
What do you call something that goes against the spirit of the law, but is legal when interpreting the law to the letter?
Why not use SQL instead of GraphQL?
Suffixes -unt and -ut-
TGV timetables / schedules?
I’m planning on buying a laser printer but concerned about the life cycle of toner in the machine
A newer friend of my brother's gave him a load of baseball cards that are supposedly extremely valuable. Is this a scam?
How old can references or sources in a thesis be?
Email Account under attack (really) - anything I can do?
Reset stored values at pagebreaks and environment boundaries
How to properly use DeclareOption within a macroHow to expand values stored in a token defined by newtoksText environment with vertical header and borderRegarding variable names and values of variables inside macrosConditional to begin and end some environmentnew environment with one optional and second must have argumentsSuspending environments and resuming by another environmentTerminate and Start and environment from within the environmentWhy expl3 booleans values are printed as Γ and ∆ (or as ` and ́ )?pgfplotstable - Make rows bold and add a backgroup color using values from two columnsEnvironment with argument and optional argument
Based on this question, I have created a simple macro that prints and stores its argument, and if it is issued again with the identical argument it prints nothing:
% !TEX TS-program = xelatexmk
RequirePackage{filecontents}
begin{filecontents}{mypackage.sty}
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{mypackage}
newenvironment{myenv}{ignorespaces}{parignorespacesafterend}
DeclareOption{skiprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@skip}%
}
DeclareOption{keeprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@keep}%
}
ExecuteOptions{keeprepetitions}
ProcessOptionsrelax
RequirePackage{xifthen}
defmypackage@storedval{} % create a macro to later store a value in
newcommand{mycommand}[1]{%
ifthenelse{isempty{#1}}
{% if empty just print an empty line
mbox{}%
}
{% if not empty
mypackage@print{#1}%
defmypackage@storedval{#1}%
}%
}
defmypackage@print@skip#1{%
ifthenelse{equal{#1}{mypackage@storedval}}
{mbox{}}
{#1}%
}
defmypackage@print@keep#1{#1\}
end{filecontents}
documentclass{article}
usepackage[skiprepetitions]{mypackage}
begin{document}
begin{myenv}
mycommand{A} \ %A
mycommand{A} \ %empty
mycommand{A} \ %empty
mycommand{} \ %empty
mycommand{B} \ %B
mycommand{C} \ %C
mycommand{C} \ %empty
mycommand{A} \ %A
end{myenv}
begin{myenv}
mycommand{A} \ %A
mycommand{A} \ %empty
newpage
mycommand{A} \ %A
end{myenv}
end{document}
I would like to now have it "reset" or "forget" what is stored at pagebreaks and boundaries of a specific environment, so that on a new page, or in a new environment it does print its argument even if the previous one was identical.
Outcommented in the document above are the values that I expect to see.
macros conditionals
add a comment |
Based on this question, I have created a simple macro that prints and stores its argument, and if it is issued again with the identical argument it prints nothing:
% !TEX TS-program = xelatexmk
RequirePackage{filecontents}
begin{filecontents}{mypackage.sty}
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{mypackage}
newenvironment{myenv}{ignorespaces}{parignorespacesafterend}
DeclareOption{skiprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@skip}%
}
DeclareOption{keeprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@keep}%
}
ExecuteOptions{keeprepetitions}
ProcessOptionsrelax
RequirePackage{xifthen}
defmypackage@storedval{} % create a macro to later store a value in
newcommand{mycommand}[1]{%
ifthenelse{isempty{#1}}
{% if empty just print an empty line
mbox{}%
}
{% if not empty
mypackage@print{#1}%
defmypackage@storedval{#1}%
}%
}
defmypackage@print@skip#1{%
ifthenelse{equal{#1}{mypackage@storedval}}
{mbox{}}
{#1}%
}
defmypackage@print@keep#1{#1\}
end{filecontents}
documentclass{article}
usepackage[skiprepetitions]{mypackage}
begin{document}
begin{myenv}
mycommand{A} \ %A
mycommand{A} \ %empty
mycommand{A} \ %empty
mycommand{} \ %empty
mycommand{B} \ %B
mycommand{C} \ %C
mycommand{C} \ %empty
mycommand{A} \ %A
end{myenv}
begin{myenv}
mycommand{A} \ %A
mycommand{A} \ %empty
newpage
mycommand{A} \ %A
end{myenv}
end{document}
I would like to now have it "reset" or "forget" what is stored at pagebreaks and boundaries of a specific environment, so that on a new page, or in a new environment it does print its argument even if the previous one was identical.
Outcommented in the document above are the values that I expect to see.
macros conditionals
1
in general (unless all your page breaks are forced) you would need a two pass system leaving markers and checking page numbers, eg via pageref. Fortunately there is a package for do most of the work for you, see theperpage
package.
– David Carlisle
8 hours ago
@DavidCarlisle Hmm, I don't quite understand how though. Soperpage
seems to reset counters, but how do I get it to reset the value that I'm storing in that macro? In general even at environment boundaries I don't know how to reset it.
– jan
6 hours ago
add a comment |
Based on this question, I have created a simple macro that prints and stores its argument, and if it is issued again with the identical argument it prints nothing:
% !TEX TS-program = xelatexmk
RequirePackage{filecontents}
begin{filecontents}{mypackage.sty}
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{mypackage}
newenvironment{myenv}{ignorespaces}{parignorespacesafterend}
DeclareOption{skiprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@skip}%
}
DeclareOption{keeprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@keep}%
}
ExecuteOptions{keeprepetitions}
ProcessOptionsrelax
RequirePackage{xifthen}
defmypackage@storedval{} % create a macro to later store a value in
newcommand{mycommand}[1]{%
ifthenelse{isempty{#1}}
{% if empty just print an empty line
mbox{}%
}
{% if not empty
mypackage@print{#1}%
defmypackage@storedval{#1}%
}%
}
defmypackage@print@skip#1{%
ifthenelse{equal{#1}{mypackage@storedval}}
{mbox{}}
{#1}%
}
defmypackage@print@keep#1{#1\}
end{filecontents}
documentclass{article}
usepackage[skiprepetitions]{mypackage}
begin{document}
begin{myenv}
mycommand{A} \ %A
mycommand{A} \ %empty
mycommand{A} \ %empty
mycommand{} \ %empty
mycommand{B} \ %B
mycommand{C} \ %C
mycommand{C} \ %empty
mycommand{A} \ %A
end{myenv}
begin{myenv}
mycommand{A} \ %A
mycommand{A} \ %empty
newpage
mycommand{A} \ %A
end{myenv}
end{document}
I would like to now have it "reset" or "forget" what is stored at pagebreaks and boundaries of a specific environment, so that on a new page, or in a new environment it does print its argument even if the previous one was identical.
Outcommented in the document above are the values that I expect to see.
macros conditionals
Based on this question, I have created a simple macro that prints and stores its argument, and if it is issued again with the identical argument it prints nothing:
% !TEX TS-program = xelatexmk
RequirePackage{filecontents}
begin{filecontents}{mypackage.sty}
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{mypackage}
newenvironment{myenv}{ignorespaces}{parignorespacesafterend}
DeclareOption{skiprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@skip}%
}
DeclareOption{keeprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@keep}%
}
ExecuteOptions{keeprepetitions}
ProcessOptionsrelax
RequirePackage{xifthen}
defmypackage@storedval{} % create a macro to later store a value in
newcommand{mycommand}[1]{%
ifthenelse{isempty{#1}}
{% if empty just print an empty line
mbox{}%
}
{% if not empty
mypackage@print{#1}%
defmypackage@storedval{#1}%
}%
}
defmypackage@print@skip#1{%
ifthenelse{equal{#1}{mypackage@storedval}}
{mbox{}}
{#1}%
}
defmypackage@print@keep#1{#1\}
end{filecontents}
documentclass{article}
usepackage[skiprepetitions]{mypackage}
begin{document}
begin{myenv}
mycommand{A} \ %A
mycommand{A} \ %empty
mycommand{A} \ %empty
mycommand{} \ %empty
mycommand{B} \ %B
mycommand{C} \ %C
mycommand{C} \ %empty
mycommand{A} \ %A
end{myenv}
begin{myenv}
mycommand{A} \ %A
mycommand{A} \ %empty
newpage
mycommand{A} \ %A
end{myenv}
end{document}
I would like to now have it "reset" or "forget" what is stored at pagebreaks and boundaries of a specific environment, so that on a new page, or in a new environment it does print its argument even if the previous one was identical.
Outcommented in the document above are the values that I expect to see.
macros conditionals
macros conditionals
asked 8 hours ago
janjan
1,0561519
1,0561519
1
in general (unless all your page breaks are forced) you would need a two pass system leaving markers and checking page numbers, eg via pageref. Fortunately there is a package for do most of the work for you, see theperpage
package.
– David Carlisle
8 hours ago
@DavidCarlisle Hmm, I don't quite understand how though. Soperpage
seems to reset counters, but how do I get it to reset the value that I'm storing in that macro? In general even at environment boundaries I don't know how to reset it.
– jan
6 hours ago
add a comment |
1
in general (unless all your page breaks are forced) you would need a two pass system leaving markers and checking page numbers, eg via pageref. Fortunately there is a package for do most of the work for you, see theperpage
package.
– David Carlisle
8 hours ago
@DavidCarlisle Hmm, I don't quite understand how though. Soperpage
seems to reset counters, but how do I get it to reset the value that I'm storing in that macro? In general even at environment boundaries I don't know how to reset it.
– jan
6 hours ago
1
1
in general (unless all your page breaks are forced) you would need a two pass system leaving markers and checking page numbers, eg via pageref. Fortunately there is a package for do most of the work for you, see the
perpage
package.– David Carlisle
8 hours ago
in general (unless all your page breaks are forced) you would need a two pass system leaving markers and checking page numbers, eg via pageref. Fortunately there is a package for do most of the work for you, see the
perpage
package.– David Carlisle
8 hours ago
@DavidCarlisle Hmm, I don't quite understand how though. So
perpage
seems to reset counters, but how do I get it to reset the value that I'm storing in that macro? In general even at environment boundaries I don't know how to reset it.– jan
6 hours ago
@DavidCarlisle Hmm, I don't quite understand how though. So
perpage
seems to reset counters, but how do I get it to reset the value that I'm storing in that macro? In general even at environment boundaries I don't know how to reset it.– jan
6 hours ago
add a comment |
1 Answer
1
active
oldest
votes
As far as I understood, the following does what you want (thanks to David Carlisle's comment for the hint about perpage
!):
RequirePackage{filecontents}
begin{filecontents}{mypackage.sty}
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{mypackage}
RequirePackage{perpage}
newcounter{mycounter}
MakePerPage{mycounter}
newenvironment{myenv}{%
% mycommand is only defined inside the environment
letmycommandmy@command
% Make sure the next mycommand isn't ignored, even if its argument
% matches the value stored in mypackage@storedval.
setcounter{mycounter}{0}%
ignorespaces
}{%
parignorespacesafterend
}
DeclareOption{skiprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@skip}%
}
DeclareOption{keeprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@keep}%
}
ExecuteOptions{keeprepetitions}
ProcessOptionsrelax
RequirePackage{xifthen}
defmypackage@storedval{} % create a macro to later store a value in
newcommand{my@command}[1]{%
ifthenelse{isempty{#1}}%
{% if empty just print an empty line
mbox{}%
}%
{% If this is the first stepcounter{mycounter} executed since the current
% page was started, this sets 'mycounter' to 1.
stepcounter{mycounter}%
mypackage@print{#1}%
defmypackage@storedval{#1}%
}%
}
defmypackage@print@skip#1{%
ifthenelse{cnttest{value{mycounter}}>{1}AND
equal{#1}{mypackage@storedval}}%
{mbox{}}%
{#1}%
}
defmypackage@print@keep#1{#1\}
end{filecontents}
documentclass{article}
usepackage[skiprepetitions]{mypackage}
begin{document}
setlength{parindent}{0pt}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
mycommand{A}\ %empty
mycommand{}\ %empty
mycommand{B}\ %B
mycommand{C}\ %C
mycommand{C}\ %empty
mycommand{A}\ %A
end{myenv}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
newpage
mycommand{A}\ %A
end{myenv}
end{document}
I used a new counter called mycounter
that is subject to MakePerPage{mycounter}
. This implies that the first stepcounter{mycounter}
on any given page resets mycounter
to 1,a because 1 is the default value of the optional argument of MakePerPage
.
I made it so that at the beginning of myenv
, mycounter
is set to 0. Besides, stepcounter{mycounter}
is executed whenever mycommand
is called with a non-empty argument. Therefore, after this stepcounter{mycounter}
is performed, mycounter
is equal to 1 if and only if:
this is the first
mycommand
call on the current page, or;this is the first
mycommand
call in the currentmyenv
environment.
This is the basis for the “ignoring criterion” you need. The only other thing to check is that, when we are in “possibly-ignoring mode”,b the argument passed to mycommand
differs from the saved value (since all this comes after the emptyness check).
Note that I renamed your mycommand
to my@command
and do letmycommandmy@command
only inside the myenv
environment, so that if you have a call to mycommand
that lies out of any myenv
environment, LaTeX will report an error (undefined command).
You may want to move the stepcounter{mycounter}
call at the beginning of the my@command
macro: this depends on the behavior you want when an empty argument is passed. Should it make the new state be “possibly-ignoring mode”, or should it let the state unchanged (in my code: the latter)? This is a decision that belongs to you. But since you just output an mbox{}
for empty arguments, the difference won't be very visible in general...
Footnotes
a. After two compilation runs, since the perpage
package relies on the .aux
file.
b. I.e., the argument is non-empty and the mycommand
call is neither the first-on-page nor the first-in-environment.
Works perfectly, thank you for the detailed explanation!
– jan
15 mins ago
Glad to hear that. I added a little discussion on the handling of empty arguments, because there is a policy decision to make that I believe wasn't precisely specified in the question (or else, I missed it).
– frougon
10 mins ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f483648%2freset-stored-values-at-pagebreaks-and-environment-boundaries%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
As far as I understood, the following does what you want (thanks to David Carlisle's comment for the hint about perpage
!):
RequirePackage{filecontents}
begin{filecontents}{mypackage.sty}
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{mypackage}
RequirePackage{perpage}
newcounter{mycounter}
MakePerPage{mycounter}
newenvironment{myenv}{%
% mycommand is only defined inside the environment
letmycommandmy@command
% Make sure the next mycommand isn't ignored, even if its argument
% matches the value stored in mypackage@storedval.
setcounter{mycounter}{0}%
ignorespaces
}{%
parignorespacesafterend
}
DeclareOption{skiprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@skip}%
}
DeclareOption{keeprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@keep}%
}
ExecuteOptions{keeprepetitions}
ProcessOptionsrelax
RequirePackage{xifthen}
defmypackage@storedval{} % create a macro to later store a value in
newcommand{my@command}[1]{%
ifthenelse{isempty{#1}}%
{% if empty just print an empty line
mbox{}%
}%
{% If this is the first stepcounter{mycounter} executed since the current
% page was started, this sets 'mycounter' to 1.
stepcounter{mycounter}%
mypackage@print{#1}%
defmypackage@storedval{#1}%
}%
}
defmypackage@print@skip#1{%
ifthenelse{cnttest{value{mycounter}}>{1}AND
equal{#1}{mypackage@storedval}}%
{mbox{}}%
{#1}%
}
defmypackage@print@keep#1{#1\}
end{filecontents}
documentclass{article}
usepackage[skiprepetitions]{mypackage}
begin{document}
setlength{parindent}{0pt}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
mycommand{A}\ %empty
mycommand{}\ %empty
mycommand{B}\ %B
mycommand{C}\ %C
mycommand{C}\ %empty
mycommand{A}\ %A
end{myenv}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
newpage
mycommand{A}\ %A
end{myenv}
end{document}
I used a new counter called mycounter
that is subject to MakePerPage{mycounter}
. This implies that the first stepcounter{mycounter}
on any given page resets mycounter
to 1,a because 1 is the default value of the optional argument of MakePerPage
.
I made it so that at the beginning of myenv
, mycounter
is set to 0. Besides, stepcounter{mycounter}
is executed whenever mycommand
is called with a non-empty argument. Therefore, after this stepcounter{mycounter}
is performed, mycounter
is equal to 1 if and only if:
this is the first
mycommand
call on the current page, or;this is the first
mycommand
call in the currentmyenv
environment.
This is the basis for the “ignoring criterion” you need. The only other thing to check is that, when we are in “possibly-ignoring mode”,b the argument passed to mycommand
differs from the saved value (since all this comes after the emptyness check).
Note that I renamed your mycommand
to my@command
and do letmycommandmy@command
only inside the myenv
environment, so that if you have a call to mycommand
that lies out of any myenv
environment, LaTeX will report an error (undefined command).
You may want to move the stepcounter{mycounter}
call at the beginning of the my@command
macro: this depends on the behavior you want when an empty argument is passed. Should it make the new state be “possibly-ignoring mode”, or should it let the state unchanged (in my code: the latter)? This is a decision that belongs to you. But since you just output an mbox{}
for empty arguments, the difference won't be very visible in general...
Footnotes
a. After two compilation runs, since the perpage
package relies on the .aux
file.
b. I.e., the argument is non-empty and the mycommand
call is neither the first-on-page nor the first-in-environment.
Works perfectly, thank you for the detailed explanation!
– jan
15 mins ago
Glad to hear that. I added a little discussion on the handling of empty arguments, because there is a policy decision to make that I believe wasn't precisely specified in the question (or else, I missed it).
– frougon
10 mins ago
add a comment |
As far as I understood, the following does what you want (thanks to David Carlisle's comment for the hint about perpage
!):
RequirePackage{filecontents}
begin{filecontents}{mypackage.sty}
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{mypackage}
RequirePackage{perpage}
newcounter{mycounter}
MakePerPage{mycounter}
newenvironment{myenv}{%
% mycommand is only defined inside the environment
letmycommandmy@command
% Make sure the next mycommand isn't ignored, even if its argument
% matches the value stored in mypackage@storedval.
setcounter{mycounter}{0}%
ignorespaces
}{%
parignorespacesafterend
}
DeclareOption{skiprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@skip}%
}
DeclareOption{keeprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@keep}%
}
ExecuteOptions{keeprepetitions}
ProcessOptionsrelax
RequirePackage{xifthen}
defmypackage@storedval{} % create a macro to later store a value in
newcommand{my@command}[1]{%
ifthenelse{isempty{#1}}%
{% if empty just print an empty line
mbox{}%
}%
{% If this is the first stepcounter{mycounter} executed since the current
% page was started, this sets 'mycounter' to 1.
stepcounter{mycounter}%
mypackage@print{#1}%
defmypackage@storedval{#1}%
}%
}
defmypackage@print@skip#1{%
ifthenelse{cnttest{value{mycounter}}>{1}AND
equal{#1}{mypackage@storedval}}%
{mbox{}}%
{#1}%
}
defmypackage@print@keep#1{#1\}
end{filecontents}
documentclass{article}
usepackage[skiprepetitions]{mypackage}
begin{document}
setlength{parindent}{0pt}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
mycommand{A}\ %empty
mycommand{}\ %empty
mycommand{B}\ %B
mycommand{C}\ %C
mycommand{C}\ %empty
mycommand{A}\ %A
end{myenv}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
newpage
mycommand{A}\ %A
end{myenv}
end{document}
I used a new counter called mycounter
that is subject to MakePerPage{mycounter}
. This implies that the first stepcounter{mycounter}
on any given page resets mycounter
to 1,a because 1 is the default value of the optional argument of MakePerPage
.
I made it so that at the beginning of myenv
, mycounter
is set to 0. Besides, stepcounter{mycounter}
is executed whenever mycommand
is called with a non-empty argument. Therefore, after this stepcounter{mycounter}
is performed, mycounter
is equal to 1 if and only if:
this is the first
mycommand
call on the current page, or;this is the first
mycommand
call in the currentmyenv
environment.
This is the basis for the “ignoring criterion” you need. The only other thing to check is that, when we are in “possibly-ignoring mode”,b the argument passed to mycommand
differs from the saved value (since all this comes after the emptyness check).
Note that I renamed your mycommand
to my@command
and do letmycommandmy@command
only inside the myenv
environment, so that if you have a call to mycommand
that lies out of any myenv
environment, LaTeX will report an error (undefined command).
You may want to move the stepcounter{mycounter}
call at the beginning of the my@command
macro: this depends on the behavior you want when an empty argument is passed. Should it make the new state be “possibly-ignoring mode”, or should it let the state unchanged (in my code: the latter)? This is a decision that belongs to you. But since you just output an mbox{}
for empty arguments, the difference won't be very visible in general...
Footnotes
a. After two compilation runs, since the perpage
package relies on the .aux
file.
b. I.e., the argument is non-empty and the mycommand
call is neither the first-on-page nor the first-in-environment.
Works perfectly, thank you for the detailed explanation!
– jan
15 mins ago
Glad to hear that. I added a little discussion on the handling of empty arguments, because there is a policy decision to make that I believe wasn't precisely specified in the question (or else, I missed it).
– frougon
10 mins ago
add a comment |
As far as I understood, the following does what you want (thanks to David Carlisle's comment for the hint about perpage
!):
RequirePackage{filecontents}
begin{filecontents}{mypackage.sty}
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{mypackage}
RequirePackage{perpage}
newcounter{mycounter}
MakePerPage{mycounter}
newenvironment{myenv}{%
% mycommand is only defined inside the environment
letmycommandmy@command
% Make sure the next mycommand isn't ignored, even if its argument
% matches the value stored in mypackage@storedval.
setcounter{mycounter}{0}%
ignorespaces
}{%
parignorespacesafterend
}
DeclareOption{skiprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@skip}%
}
DeclareOption{keeprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@keep}%
}
ExecuteOptions{keeprepetitions}
ProcessOptionsrelax
RequirePackage{xifthen}
defmypackage@storedval{} % create a macro to later store a value in
newcommand{my@command}[1]{%
ifthenelse{isempty{#1}}%
{% if empty just print an empty line
mbox{}%
}%
{% If this is the first stepcounter{mycounter} executed since the current
% page was started, this sets 'mycounter' to 1.
stepcounter{mycounter}%
mypackage@print{#1}%
defmypackage@storedval{#1}%
}%
}
defmypackage@print@skip#1{%
ifthenelse{cnttest{value{mycounter}}>{1}AND
equal{#1}{mypackage@storedval}}%
{mbox{}}%
{#1}%
}
defmypackage@print@keep#1{#1\}
end{filecontents}
documentclass{article}
usepackage[skiprepetitions]{mypackage}
begin{document}
setlength{parindent}{0pt}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
mycommand{A}\ %empty
mycommand{}\ %empty
mycommand{B}\ %B
mycommand{C}\ %C
mycommand{C}\ %empty
mycommand{A}\ %A
end{myenv}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
newpage
mycommand{A}\ %A
end{myenv}
end{document}
I used a new counter called mycounter
that is subject to MakePerPage{mycounter}
. This implies that the first stepcounter{mycounter}
on any given page resets mycounter
to 1,a because 1 is the default value of the optional argument of MakePerPage
.
I made it so that at the beginning of myenv
, mycounter
is set to 0. Besides, stepcounter{mycounter}
is executed whenever mycommand
is called with a non-empty argument. Therefore, after this stepcounter{mycounter}
is performed, mycounter
is equal to 1 if and only if:
this is the first
mycommand
call on the current page, or;this is the first
mycommand
call in the currentmyenv
environment.
This is the basis for the “ignoring criterion” you need. The only other thing to check is that, when we are in “possibly-ignoring mode”,b the argument passed to mycommand
differs from the saved value (since all this comes after the emptyness check).
Note that I renamed your mycommand
to my@command
and do letmycommandmy@command
only inside the myenv
environment, so that if you have a call to mycommand
that lies out of any myenv
environment, LaTeX will report an error (undefined command).
You may want to move the stepcounter{mycounter}
call at the beginning of the my@command
macro: this depends on the behavior you want when an empty argument is passed. Should it make the new state be “possibly-ignoring mode”, or should it let the state unchanged (in my code: the latter)? This is a decision that belongs to you. But since you just output an mbox{}
for empty arguments, the difference won't be very visible in general...
Footnotes
a. After two compilation runs, since the perpage
package relies on the .aux
file.
b. I.e., the argument is non-empty and the mycommand
call is neither the first-on-page nor the first-in-environment.
As far as I understood, the following does what you want (thanks to David Carlisle's comment for the hint about perpage
!):
RequirePackage{filecontents}
begin{filecontents}{mypackage.sty}
NeedsTeXFormat{LaTeX2e}
ProvidesPackage{mypackage}
RequirePackage{perpage}
newcounter{mycounter}
MakePerPage{mycounter}
newenvironment{myenv}{%
% mycommand is only defined inside the environment
letmycommandmy@command
% Make sure the next mycommand isn't ignored, even if its argument
% matches the value stored in mypackage@storedval.
setcounter{mycounter}{0}%
ignorespaces
}{%
parignorespacesafterend
}
DeclareOption{skiprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@skip}%
}
DeclareOption{keeprepetitions}{%
AtBeginDocument{letmypackage@printmypackage@print@keep}%
}
ExecuteOptions{keeprepetitions}
ProcessOptionsrelax
RequirePackage{xifthen}
defmypackage@storedval{} % create a macro to later store a value in
newcommand{my@command}[1]{%
ifthenelse{isempty{#1}}%
{% if empty just print an empty line
mbox{}%
}%
{% If this is the first stepcounter{mycounter} executed since the current
% page was started, this sets 'mycounter' to 1.
stepcounter{mycounter}%
mypackage@print{#1}%
defmypackage@storedval{#1}%
}%
}
defmypackage@print@skip#1{%
ifthenelse{cnttest{value{mycounter}}>{1}AND
equal{#1}{mypackage@storedval}}%
{mbox{}}%
{#1}%
}
defmypackage@print@keep#1{#1\}
end{filecontents}
documentclass{article}
usepackage[skiprepetitions]{mypackage}
begin{document}
setlength{parindent}{0pt}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
mycommand{A}\ %empty
mycommand{}\ %empty
mycommand{B}\ %B
mycommand{C}\ %C
mycommand{C}\ %empty
mycommand{A}\ %A
end{myenv}
begin{myenv}
mycommand{A}\ %A
mycommand{A}\ %empty
newpage
mycommand{A}\ %A
end{myenv}
end{document}
I used a new counter called mycounter
that is subject to MakePerPage{mycounter}
. This implies that the first stepcounter{mycounter}
on any given page resets mycounter
to 1,a because 1 is the default value of the optional argument of MakePerPage
.
I made it so that at the beginning of myenv
, mycounter
is set to 0. Besides, stepcounter{mycounter}
is executed whenever mycommand
is called with a non-empty argument. Therefore, after this stepcounter{mycounter}
is performed, mycounter
is equal to 1 if and only if:
this is the first
mycommand
call on the current page, or;this is the first
mycommand
call in the currentmyenv
environment.
This is the basis for the “ignoring criterion” you need. The only other thing to check is that, when we are in “possibly-ignoring mode”,b the argument passed to mycommand
differs from the saved value (since all this comes after the emptyness check).
Note that I renamed your mycommand
to my@command
and do letmycommandmy@command
only inside the myenv
environment, so that if you have a call to mycommand
that lies out of any myenv
environment, LaTeX will report an error (undefined command).
You may want to move the stepcounter{mycounter}
call at the beginning of the my@command
macro: this depends on the behavior you want when an empty argument is passed. Should it make the new state be “possibly-ignoring mode”, or should it let the state unchanged (in my code: the latter)? This is a decision that belongs to you. But since you just output an mbox{}
for empty arguments, the difference won't be very visible in general...
Footnotes
a. After two compilation runs, since the perpage
package relies on the .aux
file.
b. I.e., the argument is non-empty and the mycommand
call is neither the first-on-page nor the first-in-environment.
edited 11 mins ago
answered 31 mins ago
frougonfrougon
850711
850711
Works perfectly, thank you for the detailed explanation!
– jan
15 mins ago
Glad to hear that. I added a little discussion on the handling of empty arguments, because there is a policy decision to make that I believe wasn't precisely specified in the question (or else, I missed it).
– frougon
10 mins ago
add a comment |
Works perfectly, thank you for the detailed explanation!
– jan
15 mins ago
Glad to hear that. I added a little discussion on the handling of empty arguments, because there is a policy decision to make that I believe wasn't precisely specified in the question (or else, I missed it).
– frougon
10 mins ago
Works perfectly, thank you for the detailed explanation!
– jan
15 mins ago
Works perfectly, thank you for the detailed explanation!
– jan
15 mins ago
Glad to hear that. I added a little discussion on the handling of empty arguments, because there is a policy decision to make that I believe wasn't precisely specified in the question (or else, I missed it).
– frougon
10 mins ago
Glad to hear that. I added a little discussion on the handling of empty arguments, because there is a policy decision to make that I believe wasn't precisely specified in the question (or else, I missed it).
– frougon
10 mins ago
add a comment |
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f483648%2freset-stored-values-at-pagebreaks-and-environment-boundaries%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
in general (unless all your page breaks are forced) you would need a two pass system leaving markers and checking page numbers, eg via pageref. Fortunately there is a package for do most of the work for you, see the
perpage
package.– David Carlisle
8 hours ago
@DavidCarlisle Hmm, I don't quite understand how though. So
perpage
seems to reset counters, but how do I get it to reset the value that I'm storing in that macro? In general even at environment boundaries I don't know how to reset it.– jan
6 hours ago