Environment with a switch
I am trying to build an environment with a switch, so that -- when turned on - only the text in the Brackets appear in the pdf file.
It would be great, if exceptions are possible and for marked* items the whole text could be printed.
Does something like this exist? I could not find an example.
documentclass{scrreprt}
usepackage{enumerate}
begin{document}
begin{description}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{description}
end{document}
macros environments
add a comment |
I am trying to build an environment with a switch, so that -- when turned on - only the text in the Brackets appear in the pdf file.
It would be great, if exceptions are possible and for marked* items the whole text could be printed.
Does something like this exist? I could not find an example.
documentclass{scrreprt}
usepackage{enumerate}
begin{document}
begin{description}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{description}
end{document}
macros environments
add a comment |
I am trying to build an environment with a switch, so that -- when turned on - only the text in the Brackets appear in the pdf file.
It would be great, if exceptions are possible and for marked* items the whole text could be printed.
Does something like this exist? I could not find an example.
documentclass{scrreprt}
usepackage{enumerate}
begin{document}
begin{description}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{description}
end{document}
macros environments
I am trying to build an environment with a switch, so that -- when turned on - only the text in the Brackets appear in the pdf file.
It would be great, if exceptions are possible and for marked* items the whole text could be printed.
Does something like this exist? I could not find an example.
documentclass{scrreprt}
usepackage{enumerate}
begin{document}
begin{description}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{description}
end{document}
macros environments
macros environments
edited Oct 10 '17 at 15:34
Andrew
30.8k34482
30.8k34482
asked Oct 10 '17 at 14:04
C.-P.C.-P.
545
545
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
You can use environ
for manipulating the environment's contents more easily.
documentclass{article}
usepackage{xparse,environ}
ExplSyntaxOn
NewEnviron{xdesc}
{
begin{description}
cp_xdesc_main:NV xdescitemshow BODY
end{description}
}
NewEnviron{xdesc*}
{
begin{description}
cp_xdesc_main:NV xdescitemhide BODY
end{description}
}
cs_new_protected:Nn cp_xdesc_main:Nn
{
seq_set_split:Nnn l_cp_xdesc_items_in_seq { item } { #2 }
seq_pop_left:NN l_cp_xdesc_items_in_seq l_tmpa_tl
seq_clear:N l_cp_xdesc_items_out_seq
seq_map_inline:Nn l_cp_xdesc_items_in_seq
{
seq_put_right:Nn l_cp_xdesc_items_out_seq { #1 ##1 endxdescitem }
}
seq_use:Nn l_cp_xdesc_items_out_seq { }
}
cs_generate_variant:Nn cp_xdesc_main:Nn { NV }
NewDocumentCommand{xdescitemshow}{sO{}+u{endxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{endxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
The idea is to collect the contents and splitting it at item
; the first item will be empty and we throw it away. Then we process each item by adding in front of it either xdescitemshow
or xdescitemhide
and ending them with the sentinel endxdescitem
; the two commands process their arguments inserting item
, collecting the optional argument (and possibly the *
), then printing or discarding the following text up to endxdescitem
.
Update March 2019
With new features of expl3
(seq_map_variable:NNn
) and xparse
(the implementation of features alike to environ
), the code can be simplified.
documentclass{article}
usepackage{xparse}
ExplSyntaxOn
NewDocumentEnvironment{xdesc}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemshow { #1 }
end{description}
}{}
NewDocumentEnvironment{xdesc*}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemhide { #1 }
end{description}
}{}
seq_new:N l_cp_xdesc_items_seq
tl_new:N l__cp_xdesc_temp_tl
cs_new_protected:Nn cp_xdesc_main:Nn
{
% split the input at item
seq_set_split:Nnn l_cp_xdesc_items_seq { item } { #2 }
% throw away the first element, that's empty
seq_pop_left:NN l_cp_xdesc_items_seq l_tmpa_tl
%
seq_map_variable:NNn l_cp_xdesc_items_seq l__cp_xdesc_temp_tl
{
exp_last_unbraced:NV #1 l__cp_xdesc_temp_tl stopxdescitem
}
}
NewDocumentCommand{xdescitemshow}{sO{}+u{stopxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{stopxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
NewDocumentCommand{stopxdescitem}{}{} % for safety
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
That's clever: so you splitBODY
usingitem
and then process the pieces. I'm still wrapping my head around around expl3: why do you usecs_generate_variant:Nn cp_xdesc_main:Nn { NV }
rather thancs_new_protected:NV cp_xdesc_main:Nn{...}
? Does the latter not exist?
– Andrew
Oct 10 '17 at 16:17
1
@Andrew The latter would not mean the same thing.cp_xdesc_main:NV
absorbs as its second argument the contents of a variable and passing it tocp_xdesc_main:Nn
as if it were explicit.
– egreg
Oct 10 '17 at 16:54
add a comment |
I don't know of a package that does this. If you are prepared to enclose the "item text" in braces so that for each item you type something like:
Item[ABC]{12345}
then this is relatively straightforward to do using the xparse package. All that you need to do is define an Item
command that takes three arguments:
- an optional
*
- an optional label for the
item
command, and, - the "item text"
The Item
command then processes the input using the tools described in the (see the xparse](https://www.ctan.org/pkg/xparse) manual and then does the appropriate things.
For example, you get the output
using the code:
documentclass{scrreprt}
usepackage{enumerate}
usepackage{xparse}
newififMySwitch% a "switch" for turning othe item text on/off
NewDocumentCommandItem{ som }{% *[label]{text}
IfBooleanTF{#1}{ IfNoValueTF{#2}{item #3}{item[#2]#3} }
{IfNoValueTF{#2}{item}{item[#2]}ifMySwitch #3fi}
}
begin{document}
Switched on: MySwitchtrue
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
Switched off MySwitchfalse
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
end{document}
If you are not happy enclosing the "item text" in braces this is slightly trickier. The easiest way out that I see is to assume that the "item text" contains at most one paragraph, which seems reasonable to me, and then require that every item ends with a blank line. In particular, the very last item needs a blank line before the end{Description}
.
If you assume this then you can essentially repeat the code above but now the item command delegates everything to a greedyItem
command that reads in everything up to the end of the next paragraph as the item text. For LaTeX the "end of the next paragraph" means the next par
, which is why par
appears after the #3
in the definition of greedyItem
. The following code achieves this:
documentclass{scrreprt}
usepackage{enumitem}
newlist{Description}{description}{3}% a new description environment
setlist[Description]{before=letitemItem}% in which the switch is automatic
letrealItem=item% save the "real" item for future use
usepackage{xparse}
newififMySwitch% switch on/switch off
defgreedyItem[#1][#2]#3par{% #3 = until end of paragraph
IfBooleanTF{#1}{ IfNoValueTF{#2}{realItem #3}{realItem[#2]#3} }%
{IfNoValueTF{#2}{realItem}{realItem[#2]}ifMySwitch #3fi}%
}
NewDocumentCommandItem{ so }{greedyItem[#1][#2]}
begin{document}
Switched on: MySwitchtrue
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
Switched off MySwitchfalse
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
end{document}
Btw, I have switched to using the enumitem package, which I prefer, and added a few bells and whistles to hide the code inside a new Description
environment, which is the just the usual description
environment with your switch automatically incorporated. The output is the same as before.
Thanks a lot. I will test both solutions. Very great. Thank you very much.
– C.-P.
Oct 10 '17 at 15:54
@C.-P. You thank on TeX.SX by up-voting and awarding a green tick to the best answer, if any, that answers your question. You should go back over your previous posts and do this.
– Andrew
Oct 10 '17 at 15:58
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%2f395473%2fenvironment-with-a-switch%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can use environ
for manipulating the environment's contents more easily.
documentclass{article}
usepackage{xparse,environ}
ExplSyntaxOn
NewEnviron{xdesc}
{
begin{description}
cp_xdesc_main:NV xdescitemshow BODY
end{description}
}
NewEnviron{xdesc*}
{
begin{description}
cp_xdesc_main:NV xdescitemhide BODY
end{description}
}
cs_new_protected:Nn cp_xdesc_main:Nn
{
seq_set_split:Nnn l_cp_xdesc_items_in_seq { item } { #2 }
seq_pop_left:NN l_cp_xdesc_items_in_seq l_tmpa_tl
seq_clear:N l_cp_xdesc_items_out_seq
seq_map_inline:Nn l_cp_xdesc_items_in_seq
{
seq_put_right:Nn l_cp_xdesc_items_out_seq { #1 ##1 endxdescitem }
}
seq_use:Nn l_cp_xdesc_items_out_seq { }
}
cs_generate_variant:Nn cp_xdesc_main:Nn { NV }
NewDocumentCommand{xdescitemshow}{sO{}+u{endxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{endxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
The idea is to collect the contents and splitting it at item
; the first item will be empty and we throw it away. Then we process each item by adding in front of it either xdescitemshow
or xdescitemhide
and ending them with the sentinel endxdescitem
; the two commands process their arguments inserting item
, collecting the optional argument (and possibly the *
), then printing or discarding the following text up to endxdescitem
.
Update March 2019
With new features of expl3
(seq_map_variable:NNn
) and xparse
(the implementation of features alike to environ
), the code can be simplified.
documentclass{article}
usepackage{xparse}
ExplSyntaxOn
NewDocumentEnvironment{xdesc}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemshow { #1 }
end{description}
}{}
NewDocumentEnvironment{xdesc*}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemhide { #1 }
end{description}
}{}
seq_new:N l_cp_xdesc_items_seq
tl_new:N l__cp_xdesc_temp_tl
cs_new_protected:Nn cp_xdesc_main:Nn
{
% split the input at item
seq_set_split:Nnn l_cp_xdesc_items_seq { item } { #2 }
% throw away the first element, that's empty
seq_pop_left:NN l_cp_xdesc_items_seq l_tmpa_tl
%
seq_map_variable:NNn l_cp_xdesc_items_seq l__cp_xdesc_temp_tl
{
exp_last_unbraced:NV #1 l__cp_xdesc_temp_tl stopxdescitem
}
}
NewDocumentCommand{xdescitemshow}{sO{}+u{stopxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{stopxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
NewDocumentCommand{stopxdescitem}{}{} % for safety
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
That's clever: so you splitBODY
usingitem
and then process the pieces. I'm still wrapping my head around around expl3: why do you usecs_generate_variant:Nn cp_xdesc_main:Nn { NV }
rather thancs_new_protected:NV cp_xdesc_main:Nn{...}
? Does the latter not exist?
– Andrew
Oct 10 '17 at 16:17
1
@Andrew The latter would not mean the same thing.cp_xdesc_main:NV
absorbs as its second argument the contents of a variable and passing it tocp_xdesc_main:Nn
as if it were explicit.
– egreg
Oct 10 '17 at 16:54
add a comment |
You can use environ
for manipulating the environment's contents more easily.
documentclass{article}
usepackage{xparse,environ}
ExplSyntaxOn
NewEnviron{xdesc}
{
begin{description}
cp_xdesc_main:NV xdescitemshow BODY
end{description}
}
NewEnviron{xdesc*}
{
begin{description}
cp_xdesc_main:NV xdescitemhide BODY
end{description}
}
cs_new_protected:Nn cp_xdesc_main:Nn
{
seq_set_split:Nnn l_cp_xdesc_items_in_seq { item } { #2 }
seq_pop_left:NN l_cp_xdesc_items_in_seq l_tmpa_tl
seq_clear:N l_cp_xdesc_items_out_seq
seq_map_inline:Nn l_cp_xdesc_items_in_seq
{
seq_put_right:Nn l_cp_xdesc_items_out_seq { #1 ##1 endxdescitem }
}
seq_use:Nn l_cp_xdesc_items_out_seq { }
}
cs_generate_variant:Nn cp_xdesc_main:Nn { NV }
NewDocumentCommand{xdescitemshow}{sO{}+u{endxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{endxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
The idea is to collect the contents and splitting it at item
; the first item will be empty and we throw it away. Then we process each item by adding in front of it either xdescitemshow
or xdescitemhide
and ending them with the sentinel endxdescitem
; the two commands process their arguments inserting item
, collecting the optional argument (and possibly the *
), then printing or discarding the following text up to endxdescitem
.
Update March 2019
With new features of expl3
(seq_map_variable:NNn
) and xparse
(the implementation of features alike to environ
), the code can be simplified.
documentclass{article}
usepackage{xparse}
ExplSyntaxOn
NewDocumentEnvironment{xdesc}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemshow { #1 }
end{description}
}{}
NewDocumentEnvironment{xdesc*}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemhide { #1 }
end{description}
}{}
seq_new:N l_cp_xdesc_items_seq
tl_new:N l__cp_xdesc_temp_tl
cs_new_protected:Nn cp_xdesc_main:Nn
{
% split the input at item
seq_set_split:Nnn l_cp_xdesc_items_seq { item } { #2 }
% throw away the first element, that's empty
seq_pop_left:NN l_cp_xdesc_items_seq l_tmpa_tl
%
seq_map_variable:NNn l_cp_xdesc_items_seq l__cp_xdesc_temp_tl
{
exp_last_unbraced:NV #1 l__cp_xdesc_temp_tl stopxdescitem
}
}
NewDocumentCommand{xdescitemshow}{sO{}+u{stopxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{stopxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
NewDocumentCommand{stopxdescitem}{}{} % for safety
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
That's clever: so you splitBODY
usingitem
and then process the pieces. I'm still wrapping my head around around expl3: why do you usecs_generate_variant:Nn cp_xdesc_main:Nn { NV }
rather thancs_new_protected:NV cp_xdesc_main:Nn{...}
? Does the latter not exist?
– Andrew
Oct 10 '17 at 16:17
1
@Andrew The latter would not mean the same thing.cp_xdesc_main:NV
absorbs as its second argument the contents of a variable and passing it tocp_xdesc_main:Nn
as if it were explicit.
– egreg
Oct 10 '17 at 16:54
add a comment |
You can use environ
for manipulating the environment's contents more easily.
documentclass{article}
usepackage{xparse,environ}
ExplSyntaxOn
NewEnviron{xdesc}
{
begin{description}
cp_xdesc_main:NV xdescitemshow BODY
end{description}
}
NewEnviron{xdesc*}
{
begin{description}
cp_xdesc_main:NV xdescitemhide BODY
end{description}
}
cs_new_protected:Nn cp_xdesc_main:Nn
{
seq_set_split:Nnn l_cp_xdesc_items_in_seq { item } { #2 }
seq_pop_left:NN l_cp_xdesc_items_in_seq l_tmpa_tl
seq_clear:N l_cp_xdesc_items_out_seq
seq_map_inline:Nn l_cp_xdesc_items_in_seq
{
seq_put_right:Nn l_cp_xdesc_items_out_seq { #1 ##1 endxdescitem }
}
seq_use:Nn l_cp_xdesc_items_out_seq { }
}
cs_generate_variant:Nn cp_xdesc_main:Nn { NV }
NewDocumentCommand{xdescitemshow}{sO{}+u{endxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{endxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
The idea is to collect the contents and splitting it at item
; the first item will be empty and we throw it away. Then we process each item by adding in front of it either xdescitemshow
or xdescitemhide
and ending them with the sentinel endxdescitem
; the two commands process their arguments inserting item
, collecting the optional argument (and possibly the *
), then printing or discarding the following text up to endxdescitem
.
Update March 2019
With new features of expl3
(seq_map_variable:NNn
) and xparse
(the implementation of features alike to environ
), the code can be simplified.
documentclass{article}
usepackage{xparse}
ExplSyntaxOn
NewDocumentEnvironment{xdesc}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemshow { #1 }
end{description}
}{}
NewDocumentEnvironment{xdesc*}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemhide { #1 }
end{description}
}{}
seq_new:N l_cp_xdesc_items_seq
tl_new:N l__cp_xdesc_temp_tl
cs_new_protected:Nn cp_xdesc_main:Nn
{
% split the input at item
seq_set_split:Nnn l_cp_xdesc_items_seq { item } { #2 }
% throw away the first element, that's empty
seq_pop_left:NN l_cp_xdesc_items_seq l_tmpa_tl
%
seq_map_variable:NNn l_cp_xdesc_items_seq l__cp_xdesc_temp_tl
{
exp_last_unbraced:NV #1 l__cp_xdesc_temp_tl stopxdescitem
}
}
NewDocumentCommand{xdescitemshow}{sO{}+u{stopxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{stopxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
NewDocumentCommand{stopxdescitem}{}{} % for safety
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
You can use environ
for manipulating the environment's contents more easily.
documentclass{article}
usepackage{xparse,environ}
ExplSyntaxOn
NewEnviron{xdesc}
{
begin{description}
cp_xdesc_main:NV xdescitemshow BODY
end{description}
}
NewEnviron{xdesc*}
{
begin{description}
cp_xdesc_main:NV xdescitemhide BODY
end{description}
}
cs_new_protected:Nn cp_xdesc_main:Nn
{
seq_set_split:Nnn l_cp_xdesc_items_in_seq { item } { #2 }
seq_pop_left:NN l_cp_xdesc_items_in_seq l_tmpa_tl
seq_clear:N l_cp_xdesc_items_out_seq
seq_map_inline:Nn l_cp_xdesc_items_in_seq
{
seq_put_right:Nn l_cp_xdesc_items_out_seq { #1 ##1 endxdescitem }
}
seq_use:Nn l_cp_xdesc_items_out_seq { }
}
cs_generate_variant:Nn cp_xdesc_main:Nn { NV }
NewDocumentCommand{xdescitemshow}{sO{}+u{endxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{endxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
The idea is to collect the contents and splitting it at item
; the first item will be empty and we throw it away. Then we process each item by adding in front of it either xdescitemshow
or xdescitemhide
and ending them with the sentinel endxdescitem
; the two commands process their arguments inserting item
, collecting the optional argument (and possibly the *
), then printing or discarding the following text up to endxdescitem
.
Update March 2019
With new features of expl3
(seq_map_variable:NNn
) and xparse
(the implementation of features alike to environ
), the code can be simplified.
documentclass{article}
usepackage{xparse}
ExplSyntaxOn
NewDocumentEnvironment{xdesc}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemshow { #1 }
end{description}
}{}
NewDocumentEnvironment{xdesc*}{+b}
{
begin{description}
cp_xdesc_main:Nn xdescitemhide { #1 }
end{description}
}{}
seq_new:N l_cp_xdesc_items_seq
tl_new:N l__cp_xdesc_temp_tl
cs_new_protected:Nn cp_xdesc_main:Nn
{
% split the input at item
seq_set_split:Nnn l_cp_xdesc_items_seq { item } { #2 }
% throw away the first element, that's empty
seq_pop_left:NN l_cp_xdesc_items_seq l_tmpa_tl
%
seq_map_variable:NNn l_cp_xdesc_items_seq l__cp_xdesc_temp_tl
{
exp_last_unbraced:NV #1 l__cp_xdesc_temp_tl stopxdescitem
}
}
NewDocumentCommand{xdescitemshow}{sO{}+u{stopxdescitem}}
{
item[#2] #3
}
NewDocumentCommand{xdescitemhide}{sO{}+u{stopxdescitem}}
{
item[#2] IfBooleanT{#1}{#3}
}
NewDocumentCommand{stopxdescitem}{}{} % for safety
ExplSyntaxOff
begin{document}
section{Show}
begin{xdesc}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc}
section{Hide}
begin{xdesc*}
item[ABC] 12345
item[CDEF] 098765
item*[xxxx] yyyyy
end{xdesc*}
end{document}
edited Mar 9 at 11:24
answered Oct 10 '17 at 16:05
egregegreg
727k8819223231
727k8819223231
That's clever: so you splitBODY
usingitem
and then process the pieces. I'm still wrapping my head around around expl3: why do you usecs_generate_variant:Nn cp_xdesc_main:Nn { NV }
rather thancs_new_protected:NV cp_xdesc_main:Nn{...}
? Does the latter not exist?
– Andrew
Oct 10 '17 at 16:17
1
@Andrew The latter would not mean the same thing.cp_xdesc_main:NV
absorbs as its second argument the contents of a variable and passing it tocp_xdesc_main:Nn
as if it were explicit.
– egreg
Oct 10 '17 at 16:54
add a comment |
That's clever: so you splitBODY
usingitem
and then process the pieces. I'm still wrapping my head around around expl3: why do you usecs_generate_variant:Nn cp_xdesc_main:Nn { NV }
rather thancs_new_protected:NV cp_xdesc_main:Nn{...}
? Does the latter not exist?
– Andrew
Oct 10 '17 at 16:17
1
@Andrew The latter would not mean the same thing.cp_xdesc_main:NV
absorbs as its second argument the contents of a variable and passing it tocp_xdesc_main:Nn
as if it were explicit.
– egreg
Oct 10 '17 at 16:54
That's clever: so you split
BODY
using item
and then process the pieces. I'm still wrapping my head around around expl3: why do you use cs_generate_variant:Nn cp_xdesc_main:Nn { NV }
rather than cs_new_protected:NV cp_xdesc_main:Nn{...}
? Does the latter not exist?– Andrew
Oct 10 '17 at 16:17
That's clever: so you split
BODY
using item
and then process the pieces. I'm still wrapping my head around around expl3: why do you use cs_generate_variant:Nn cp_xdesc_main:Nn { NV }
rather than cs_new_protected:NV cp_xdesc_main:Nn{...}
? Does the latter not exist?– Andrew
Oct 10 '17 at 16:17
1
1
@Andrew The latter would not mean the same thing.
cp_xdesc_main:NV
absorbs as its second argument the contents of a variable and passing it to cp_xdesc_main:Nn
as if it were explicit.– egreg
Oct 10 '17 at 16:54
@Andrew The latter would not mean the same thing.
cp_xdesc_main:NV
absorbs as its second argument the contents of a variable and passing it to cp_xdesc_main:Nn
as if it were explicit.– egreg
Oct 10 '17 at 16:54
add a comment |
I don't know of a package that does this. If you are prepared to enclose the "item text" in braces so that for each item you type something like:
Item[ABC]{12345}
then this is relatively straightforward to do using the xparse package. All that you need to do is define an Item
command that takes three arguments:
- an optional
*
- an optional label for the
item
command, and, - the "item text"
The Item
command then processes the input using the tools described in the (see the xparse](https://www.ctan.org/pkg/xparse) manual and then does the appropriate things.
For example, you get the output
using the code:
documentclass{scrreprt}
usepackage{enumerate}
usepackage{xparse}
newififMySwitch% a "switch" for turning othe item text on/off
NewDocumentCommandItem{ som }{% *[label]{text}
IfBooleanTF{#1}{ IfNoValueTF{#2}{item #3}{item[#2]#3} }
{IfNoValueTF{#2}{item}{item[#2]}ifMySwitch #3fi}
}
begin{document}
Switched on: MySwitchtrue
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
Switched off MySwitchfalse
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
end{document}
If you are not happy enclosing the "item text" in braces this is slightly trickier. The easiest way out that I see is to assume that the "item text" contains at most one paragraph, which seems reasonable to me, and then require that every item ends with a blank line. In particular, the very last item needs a blank line before the end{Description}
.
If you assume this then you can essentially repeat the code above but now the item command delegates everything to a greedyItem
command that reads in everything up to the end of the next paragraph as the item text. For LaTeX the "end of the next paragraph" means the next par
, which is why par
appears after the #3
in the definition of greedyItem
. The following code achieves this:
documentclass{scrreprt}
usepackage{enumitem}
newlist{Description}{description}{3}% a new description environment
setlist[Description]{before=letitemItem}% in which the switch is automatic
letrealItem=item% save the "real" item for future use
usepackage{xparse}
newififMySwitch% switch on/switch off
defgreedyItem[#1][#2]#3par{% #3 = until end of paragraph
IfBooleanTF{#1}{ IfNoValueTF{#2}{realItem #3}{realItem[#2]#3} }%
{IfNoValueTF{#2}{realItem}{realItem[#2]}ifMySwitch #3fi}%
}
NewDocumentCommandItem{ so }{greedyItem[#1][#2]}
begin{document}
Switched on: MySwitchtrue
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
Switched off MySwitchfalse
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
end{document}
Btw, I have switched to using the enumitem package, which I prefer, and added a few bells and whistles to hide the code inside a new Description
environment, which is the just the usual description
environment with your switch automatically incorporated. The output is the same as before.
Thanks a lot. I will test both solutions. Very great. Thank you very much.
– C.-P.
Oct 10 '17 at 15:54
@C.-P. You thank on TeX.SX by up-voting and awarding a green tick to the best answer, if any, that answers your question. You should go back over your previous posts and do this.
– Andrew
Oct 10 '17 at 15:58
add a comment |
I don't know of a package that does this. If you are prepared to enclose the "item text" in braces so that for each item you type something like:
Item[ABC]{12345}
then this is relatively straightforward to do using the xparse package. All that you need to do is define an Item
command that takes three arguments:
- an optional
*
- an optional label for the
item
command, and, - the "item text"
The Item
command then processes the input using the tools described in the (see the xparse](https://www.ctan.org/pkg/xparse) manual and then does the appropriate things.
For example, you get the output
using the code:
documentclass{scrreprt}
usepackage{enumerate}
usepackage{xparse}
newififMySwitch% a "switch" for turning othe item text on/off
NewDocumentCommandItem{ som }{% *[label]{text}
IfBooleanTF{#1}{ IfNoValueTF{#2}{item #3}{item[#2]#3} }
{IfNoValueTF{#2}{item}{item[#2]}ifMySwitch #3fi}
}
begin{document}
Switched on: MySwitchtrue
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
Switched off MySwitchfalse
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
end{document}
If you are not happy enclosing the "item text" in braces this is slightly trickier. The easiest way out that I see is to assume that the "item text" contains at most one paragraph, which seems reasonable to me, and then require that every item ends with a blank line. In particular, the very last item needs a blank line before the end{Description}
.
If you assume this then you can essentially repeat the code above but now the item command delegates everything to a greedyItem
command that reads in everything up to the end of the next paragraph as the item text. For LaTeX the "end of the next paragraph" means the next par
, which is why par
appears after the #3
in the definition of greedyItem
. The following code achieves this:
documentclass{scrreprt}
usepackage{enumitem}
newlist{Description}{description}{3}% a new description environment
setlist[Description]{before=letitemItem}% in which the switch is automatic
letrealItem=item% save the "real" item for future use
usepackage{xparse}
newififMySwitch% switch on/switch off
defgreedyItem[#1][#2]#3par{% #3 = until end of paragraph
IfBooleanTF{#1}{ IfNoValueTF{#2}{realItem #3}{realItem[#2]#3} }%
{IfNoValueTF{#2}{realItem}{realItem[#2]}ifMySwitch #3fi}%
}
NewDocumentCommandItem{ so }{greedyItem[#1][#2]}
begin{document}
Switched on: MySwitchtrue
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
Switched off MySwitchfalse
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
end{document}
Btw, I have switched to using the enumitem package, which I prefer, and added a few bells and whistles to hide the code inside a new Description
environment, which is the just the usual description
environment with your switch automatically incorporated. The output is the same as before.
Thanks a lot. I will test both solutions. Very great. Thank you very much.
– C.-P.
Oct 10 '17 at 15:54
@C.-P. You thank on TeX.SX by up-voting and awarding a green tick to the best answer, if any, that answers your question. You should go back over your previous posts and do this.
– Andrew
Oct 10 '17 at 15:58
add a comment |
I don't know of a package that does this. If you are prepared to enclose the "item text" in braces so that for each item you type something like:
Item[ABC]{12345}
then this is relatively straightforward to do using the xparse package. All that you need to do is define an Item
command that takes three arguments:
- an optional
*
- an optional label for the
item
command, and, - the "item text"
The Item
command then processes the input using the tools described in the (see the xparse](https://www.ctan.org/pkg/xparse) manual and then does the appropriate things.
For example, you get the output
using the code:
documentclass{scrreprt}
usepackage{enumerate}
usepackage{xparse}
newififMySwitch% a "switch" for turning othe item text on/off
NewDocumentCommandItem{ som }{% *[label]{text}
IfBooleanTF{#1}{ IfNoValueTF{#2}{item #3}{item[#2]#3} }
{IfNoValueTF{#2}{item}{item[#2]}ifMySwitch #3fi}
}
begin{document}
Switched on: MySwitchtrue
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
Switched off MySwitchfalse
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
end{document}
If you are not happy enclosing the "item text" in braces this is slightly trickier. The easiest way out that I see is to assume that the "item text" contains at most one paragraph, which seems reasonable to me, and then require that every item ends with a blank line. In particular, the very last item needs a blank line before the end{Description}
.
If you assume this then you can essentially repeat the code above but now the item command delegates everything to a greedyItem
command that reads in everything up to the end of the next paragraph as the item text. For LaTeX the "end of the next paragraph" means the next par
, which is why par
appears after the #3
in the definition of greedyItem
. The following code achieves this:
documentclass{scrreprt}
usepackage{enumitem}
newlist{Description}{description}{3}% a new description environment
setlist[Description]{before=letitemItem}% in which the switch is automatic
letrealItem=item% save the "real" item for future use
usepackage{xparse}
newififMySwitch% switch on/switch off
defgreedyItem[#1][#2]#3par{% #3 = until end of paragraph
IfBooleanTF{#1}{ IfNoValueTF{#2}{realItem #3}{realItem[#2]#3} }%
{IfNoValueTF{#2}{realItem}{realItem[#2]}ifMySwitch #3fi}%
}
NewDocumentCommandItem{ so }{greedyItem[#1][#2]}
begin{document}
Switched on: MySwitchtrue
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
Switched off MySwitchfalse
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
end{document}
Btw, I have switched to using the enumitem package, which I prefer, and added a few bells and whistles to hide the code inside a new Description
environment, which is the just the usual description
environment with your switch automatically incorporated. The output is the same as before.
I don't know of a package that does this. If you are prepared to enclose the "item text" in braces so that for each item you type something like:
Item[ABC]{12345}
then this is relatively straightforward to do using the xparse package. All that you need to do is define an Item
command that takes three arguments:
- an optional
*
- an optional label for the
item
command, and, - the "item text"
The Item
command then processes the input using the tools described in the (see the xparse](https://www.ctan.org/pkg/xparse) manual and then does the appropriate things.
For example, you get the output
using the code:
documentclass{scrreprt}
usepackage{enumerate}
usepackage{xparse}
newififMySwitch% a "switch" for turning othe item text on/off
NewDocumentCommandItem{ som }{% *[label]{text}
IfBooleanTF{#1}{ IfNoValueTF{#2}{item #3}{item[#2]#3} }
{IfNoValueTF{#2}{item}{item[#2]}ifMySwitch #3fi}
}
begin{document}
Switched on: MySwitchtrue
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
Switched off MySwitchfalse
begin{description}
Item[ABC]{12345}
Item[CDEF]{098765}
Item*[xxxx]{yyyyy}
end{description}
end{document}
If you are not happy enclosing the "item text" in braces this is slightly trickier. The easiest way out that I see is to assume that the "item text" contains at most one paragraph, which seems reasonable to me, and then require that every item ends with a blank line. In particular, the very last item needs a blank line before the end{Description}
.
If you assume this then you can essentially repeat the code above but now the item command delegates everything to a greedyItem
command that reads in everything up to the end of the next paragraph as the item text. For LaTeX the "end of the next paragraph" means the next par
, which is why par
appears after the #3
in the definition of greedyItem
. The following code achieves this:
documentclass{scrreprt}
usepackage{enumitem}
newlist{Description}{description}{3}% a new description environment
setlist[Description]{before=letitemItem}% in which the switch is automatic
letrealItem=item% save the "real" item for future use
usepackage{xparse}
newififMySwitch% switch on/switch off
defgreedyItem[#1][#2]#3par{% #3 = until end of paragraph
IfBooleanTF{#1}{ IfNoValueTF{#2}{realItem #3}{realItem[#2]#3} }%
{IfNoValueTF{#2}{realItem}{realItem[#2]}ifMySwitch #3fi}%
}
NewDocumentCommandItem{ so }{greedyItem[#1][#2]}
begin{document}
Switched on: MySwitchtrue
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
Switched off MySwitchfalse
begin{Description}
item[ABC]12345
item[CDEF]098765
item*[xxxx]yyyyy
end{Description}
end{document}
Btw, I have switched to using the enumitem package, which I prefer, and added a few bells and whistles to hide the code inside a new Description
environment, which is the just the usual description
environment with your switch automatically incorporated. The output is the same as before.
edited Oct 10 '17 at 15:48
answered Oct 10 '17 at 15:34
AndrewAndrew
30.8k34482
30.8k34482
Thanks a lot. I will test both solutions. Very great. Thank you very much.
– C.-P.
Oct 10 '17 at 15:54
@C.-P. You thank on TeX.SX by up-voting and awarding a green tick to the best answer, if any, that answers your question. You should go back over your previous posts and do this.
– Andrew
Oct 10 '17 at 15:58
add a comment |
Thanks a lot. I will test both solutions. Very great. Thank you very much.
– C.-P.
Oct 10 '17 at 15:54
@C.-P. You thank on TeX.SX by up-voting and awarding a green tick to the best answer, if any, that answers your question. You should go back over your previous posts and do this.
– Andrew
Oct 10 '17 at 15:58
Thanks a lot. I will test both solutions. Very great. Thank you very much.
– C.-P.
Oct 10 '17 at 15:54
Thanks a lot. I will test both solutions. Very great. Thank you very much.
– C.-P.
Oct 10 '17 at 15:54
@C.-P. You thank on TeX.SX by up-voting and awarding a green tick to the best answer, if any, that answers your question. You should go back over your previous posts and do this.
– Andrew
Oct 10 '17 at 15:58
@C.-P. You thank on TeX.SX by up-voting and awarding a green tick to the best answer, if any, that answers your question. You should go back over your previous posts and do this.
– Andrew
Oct 10 '17 at 15:58
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%2f395473%2fenvironment-with-a-switch%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