Custom label for references using tasks inside a xsim exercise
In order to create an assignment sheet, I am using the xsim
package and to create subquestions within a question, I use the package tasks
. The problem comes while referring to the subquestions. Ideally I would like the subquestions to be referred to as 1.2 or 1.3, instead they gets referred as just 1 as the MWE demonstrates. As you can see the output is really stupid.
I have these concerns
- How do I get
cref
identify the subquestions as "subquestion 1.1".? I would ideally like to issue a directive something likecrefname{subquestion}{subquestion}{subquestions}
. Thecref
invocation should also be able to distinguish between a mere question and a subquestion. - Suppose in future, I change
counter-format = tsk[1]
to
counter-format = tsk[r]
, would I get consistent output?
Something like "subquestion 1.a"?
EDIT by magguu :: please see my half-working answer and corresponding MWE
Please see the MWE::
documentclass[11pt]{article}
usepackage{tasks,cleveref,xsim}
NewTasks[counter-format = tsk[1]),
label-format = itshape,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
crefname{exercise}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
begin{document}
begin{exercise}[points=3]
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean cref{metawhy}?
end{subquestionblock}
end{exercise}
begin{exercise}[points=3]
Is there an end to stupid questions? label{stu}
begin{subquestionblock}
subquestion! Discuss why cref{metawhy} is a stupid question but cref{why} is even stupider? label{huh}
subquestion! Are both cref{huh} and cref{metawhy} both stupider that each other?
end{subquestionblock}
end{exercise}
end{document}
cross-referencing cleveref tasks ref xsim
add a comment |
In order to create an assignment sheet, I am using the xsim
package and to create subquestions within a question, I use the package tasks
. The problem comes while referring to the subquestions. Ideally I would like the subquestions to be referred to as 1.2 or 1.3, instead they gets referred as just 1 as the MWE demonstrates. As you can see the output is really stupid.
I have these concerns
- How do I get
cref
identify the subquestions as "subquestion 1.1".? I would ideally like to issue a directive something likecrefname{subquestion}{subquestion}{subquestions}
. Thecref
invocation should also be able to distinguish between a mere question and a subquestion. - Suppose in future, I change
counter-format = tsk[1]
to
counter-format = tsk[r]
, would I get consistent output?
Something like "subquestion 1.a"?
EDIT by magguu :: please see my half-working answer and corresponding MWE
Please see the MWE::
documentclass[11pt]{article}
usepackage{tasks,cleveref,xsim}
NewTasks[counter-format = tsk[1]),
label-format = itshape,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
crefname{exercise}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
begin{document}
begin{exercise}[points=3]
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean cref{metawhy}?
end{subquestionblock}
end{exercise}
begin{exercise}[points=3]
Is there an end to stupid questions? label{stu}
begin{subquestionblock}
subquestion! Discuss why cref{metawhy} is a stupid question but cref{why} is even stupider? label{huh}
subquestion! Are both cref{huh} and cref{metawhy} both stupider that each other?
end{subquestionblock}
end{exercise}
end{document}
cross-referencing cleveref tasks ref xsim
add a comment |
In order to create an assignment sheet, I am using the xsim
package and to create subquestions within a question, I use the package tasks
. The problem comes while referring to the subquestions. Ideally I would like the subquestions to be referred to as 1.2 or 1.3, instead they gets referred as just 1 as the MWE demonstrates. As you can see the output is really stupid.
I have these concerns
- How do I get
cref
identify the subquestions as "subquestion 1.1".? I would ideally like to issue a directive something likecrefname{subquestion}{subquestion}{subquestions}
. Thecref
invocation should also be able to distinguish between a mere question and a subquestion. - Suppose in future, I change
counter-format = tsk[1]
to
counter-format = tsk[r]
, would I get consistent output?
Something like "subquestion 1.a"?
EDIT by magguu :: please see my half-working answer and corresponding MWE
Please see the MWE::
documentclass[11pt]{article}
usepackage{tasks,cleveref,xsim}
NewTasks[counter-format = tsk[1]),
label-format = itshape,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
crefname{exercise}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
begin{document}
begin{exercise}[points=3]
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean cref{metawhy}?
end{subquestionblock}
end{exercise}
begin{exercise}[points=3]
Is there an end to stupid questions? label{stu}
begin{subquestionblock}
subquestion! Discuss why cref{metawhy} is a stupid question but cref{why} is even stupider? label{huh}
subquestion! Are both cref{huh} and cref{metawhy} both stupider that each other?
end{subquestionblock}
end{exercise}
end{document}
cross-referencing cleveref tasks ref xsim
In order to create an assignment sheet, I am using the xsim
package and to create subquestions within a question, I use the package tasks
. The problem comes while referring to the subquestions. Ideally I would like the subquestions to be referred to as 1.2 or 1.3, instead they gets referred as just 1 as the MWE demonstrates. As you can see the output is really stupid.
I have these concerns
- How do I get
cref
identify the subquestions as "subquestion 1.1".? I would ideally like to issue a directive something likecrefname{subquestion}{subquestion}{subquestions}
. Thecref
invocation should also be able to distinguish between a mere question and a subquestion. - Suppose in future, I change
counter-format = tsk[1]
to
counter-format = tsk[r]
, would I get consistent output?
Something like "subquestion 1.a"?
EDIT by magguu :: please see my half-working answer and corresponding MWE
Please see the MWE::
documentclass[11pt]{article}
usepackage{tasks,cleveref,xsim}
NewTasks[counter-format = tsk[1]),
label-format = itshape,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
crefname{exercise}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
begin{document}
begin{exercise}[points=3]
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean cref{metawhy}?
end{subquestionblock}
end{exercise}
begin{exercise}[points=3]
Is there an end to stupid questions? label{stu}
begin{subquestionblock}
subquestion! Discuss why cref{metawhy} is a stupid question but cref{why} is even stupider? label{huh}
subquestion! Are both cref{huh} and cref{metawhy} both stupider that each other?
end{subquestionblock}
end{exercise}
end{document}
cross-referencing cleveref tasks ref xsim
cross-referencing cleveref tasks ref xsim
edited Sep 4 at 8:44
asked Aug 31 at 11:18
magguu
37617
37617
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
After trying several things, now I have an ugly hack. It does not solve every thing and introduces some other irritants but it does solve the most vexing counter issue. For this I embed exercise
in a new environment question
which has its own counter called question
. Then the formatting code of subquestion
has a hack to increment another counter called subquestion
.
The end result is that my concern number 2 gets resolved automatically as you can see in the output image attached : the subquestion 3.1 and subquestion 3.3.
However I still cannot resolve concern number 1. I tried to use some other hacks but got embroiled in expandafter
mess. I am not posting those efforts in my MWE here.
Now I have these new concerns:
- How do I get rid of the ")" coming after every references?
- How do I change several invocations of "question" to "subquestion". To wit, "question" in 1.2 should remain unchanged but other "question"s shd change to "subquestion". I could have changed definition of
refsubq
but that would have other problems.
Please see the new MWE::
documentclass[11pt]{article}
usepackage{tasks,cleveref,xsim}
newcommand{refsubq}[1]{cref{#1}.ref{#1}}
newcounter{question}
newcounter{subquestion}[question]
newcommand{uglyhack}{refstepcounter{subquestion}itshape}
NewTasks[counter-format = tsk[1]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[counter-format = tsk[a]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblockA}[subquestion](2)
newenvironment{question}{refstepcounter{question}exercise}{endexercise}
crefname{exercise}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{subquestionblock}{subquestion}{subquestions} % fails
crefname{subquestionblockA}{subquestion}{subquestions} % fails
begin{document}
begin{question}
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean refsubq{metawhy}?
end{subquestionblock}
end{question}
begin{question}
Is there an end to stupid questions? label{stu}
begin{subquestionblockA}
subquestion! Discuss why refsubq{metawhy} is a stupid question but refsubq{why} is even stupider? label{huh}
subquestion! Are refsubq{huh} and refsubq{metawhy} both stupider than each other? label{huh2}
subquestion! Please see refsubq{goto2} for more info. label{goto}
end{subquestionblockA}
end{question}
begin{question}
I am just a question.
begin{subquestionblock}
subquestion! I am a simple subquestion unlike refsubq{huh2}.
subquestion! I am a subquestion (refsubq{self}) stupid enough to refer to myselflabel{self}.
subquestion! Please see refsubq{goto} for even more info. label{goto2}
end{subquestionblock}
end{question}
end{document}
Image ::
add a comment |
Address your request to the author of the tasks-package and make a bug report:
The code of the tasks package comes without properly commented sources, just as a .sty-file and thus is inscrutable. Same for some of the packages loaded/used by the tasks-package.
It seems that instead of using
refstepcounter
, the author of that package does his own counter-thingies, based on expl3 and using yet another one of his packages, calledcntformats
, which one has to spend hours on studying for finding out what might probably go on. According to my opinion, all this makes things even more inscrutable and, according to my opinion, is definitely not a good idea if one wishes ones own things to properly interact with common LaTeX2e-infrastructure.
Within that inscrutable package,
cs_gset:Npx
is used for defining the macro@currentlabel
. Seems this does redefine@currentlabel
globally. The LaTeX2e-kernel does never redefine@currentlabel
globally. If you do so, placing labels after ending one of thosetasks
-environments will yield wrong numbers when referencing these labels.
(Well, the
hyperref
-package does redefine@currentHref
globally, which in my opinion is a similar well-established mis-concept as it may lead to connecting references with hyperlinks to wrong targets.)
This sort of things does confuse and scare off those LaTeX-beginners who exercise the care of checking the correctness of the result while not being experienced enough for tracking down what is happening when things do not turn out correct. I saw users despairing after spending hours and days on studying inscrutable code instead of learning the relevant basics of their field of study as they were, while not yet knowing anything about these things, urged by teachers, who found another way of living out their profile neurosis, to use LaTeX and specific packages, which altogether they would never ever need again after leaving school/university.
You additionally use the package
cleveref
. This package does redefine some of the kernel-macros, e.g.,refstepcounter
and does rely on people using standard-infrastructure for doing counter-thingies, which thetasks
-package does not:
cleveref
does redefinerefstepcounter
to also define an additional macrocref@currentlabel
and does redefinelabel
to write twonewlabel
-entries to the .aux-file instead of one: The usualnewlabel
-entry whose data stems from@currentlabel
and an additionalnewlabel
-entry where the label-name has the suffix@cref
and whose data stems fromcref@currentlabel
and which delivers the data needed additionally by thecleveref
-referencing-macros.
The
tasks
-package, which does its own counter-thingies and which does redefine@currentlabel
on its own instead of using LaTeX2e-infrastructure/refstepcounter
, does not setcref@currentlabel
and thus breaks, e.g., thecleveref
package.
Inspired by your own answer/your hack I just came up with a variant where you get rid of the closing parenthese and which makes cref
possible also and which also works out when using the hyperref package.
Of course my variant does not resolve the tasks package's behavior of redefining @currentlabel
globally but does the same thing for cleveref's cref@currentlabel
.
The gist is:
I added another key "ugly-label-hook" to the tasks-package which lets you specify some tokens that get inserted whenever the tasks-package for one of its items modifies @currentlabel
.
You can use this hook for "refstepping" the "dummy"-counter for your subquestions/subanswers.
"refstepping" the "dummy"-counter makes sure the macros @currentlabel
and cref@currentlabel
are (re)defined correctly.
As the tasks-package does for whatever reason redefine @currentlabel
globally, with the "ugly-label-hook" it must be ensured that both @currentlabel
and cref@currentlabel
are (re)defined globally also.
documentclass[11pt]{article}
usepackage{hyperref}
usepackage{tasks,cleveref,xsim}
% ====Begin of patch of tasks.sty====
makeatletter
ExplSyntaxOn
% Allocate another token list for the ugly hack:
tl_new:N l__sillyugly_label_hook_tl
% Add a key "ugly-label-hook" for setting that
% token list:
keys_define:nn {tasks/list}
{
ugly-label-hook .tl_set:N = l__sillyugly_label_hook_tl ,
}
% Include the ugly-label-hook-key into the `tasks' object:
% #1: number of items
% #2: number of columns
% #3: label-format
DeclareObjectType {tasks} {3}
% the `default' template interface:
DeclareTemplateInterface {tasks} {default} {3}
{
enumerate : boolean = true ,
label : tokenlist ,
indent : length = 2.5em ,
counter-format : tokenlist = tsk[a]) ,
label-format : tokenlist ,
%----------------------------------------------------
ugly-label-hook : tokenlist ,
%----------------------------------------------------
label-width : length = 1em ,
label-offset : length = .3333em ,
item-format : tokenlist ,
after-item-skip : skip = 1ex plus 1ex minus 1ex
}
% When patching the next macro, the really unlikely marker $ with
% unusual catcode is used in ``$tasks$default$label$'':
cs_set:Nx __tasks_restore_dollar:
{ char_set_catcode:nn {36} { char_value_catcode:n {36} } }
char_set_catcode_alignment:N $
% Include the ugly-label-hook-key into the `default' template code
% and apply the hook when @currentlabel is changed:
DeclareTemplateCode {tasks} {default} {3}
{
enumerate = l__tasks_enumerate_bool ,
label = l__tasks_label_tl ,
indent = l__tasks_item_default_indent_dim ,
counter-format = l__tasks_label_pattern_tl ,
label-format = l__tasks_label_format_tl ,
%----------------------------------------------------
ugly-label-hook = l__sillyugly_label_hook_tl ,
%----------------------------------------------------
label-width = l__tasks_label_default_width_dim ,
label-offset = l__tasks_label_default_offset_dim ,
item-format = l__tasks_item_format_tl ,
after-item-skip = l__tasks_after_item_skip
}
{
AssignTemplateKeys
bool_if:NF l__tasks_label_width_bool
{
dim_set_eq:NN
l__tasks_label_width_dim
l__tasks_label_default_width_dim
}
bool_if:NF l__tasks_item_indent_bool
{
dim_set_eq:NN
l__tasks_item_indent_dim
l__tasks_item_default_indent_dim
}
bool_if:NF l__tasks_label_offset_bool
{
dim_set_eq:NN
l__tasks_label_offset_dim
l__tasks_label_default_offset_dim
}
% dim_compare:nNnT
% { l__tasks_item_indent_dim }
% <
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% {
% dim_set:Nn l__tasks_item_indent_dim
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% }
bool_if:NT l__tasks_custom_after_item_skip_bool
{
skip_set_eq:NN
l__tasks_after_item_skip
l__tasks_custom_after_item_skip
}
bool_if:NT l__tasks_custom_label_bool
{
tl_set_eq:NN
l__tasks_label_tl
l__tasks_custom_label_tl
bool_set_false:N l__tasks_enumerate_bool
}
__tasks_label_align:V l__tasks_label_align_tl
% need this for enumerate list:
bool_if:nT { !l__tasks_resume_bool && l__tasks_enumerate_bool }
{ int_gzero:N g__tasks_int }
int_set:Nn l__tasks_columns_int {#2}
% set all the items in their own coffins and join with the ground:
int_gzero:N g__tasks_current_col_num_int
int_set:Nn g__tasks_current_row_num_int {1}
tl_if_blank:VF l__tasks_custom_label_pattern_tl
{
tl_set_eq:NN
l__tasks_label_pattern_tl
l__tasks_custom_label_pattern_tl
}
tl_if_blank:VF l__tasks_custom_label_format_tl
{
tl_set_eq:NN
l__tasks_label_format_tl
l__tasks_custom_label_format_tl
}
tl_if_blank:VF l__tasks_custom_item_format_tl
{
tl_set_eq:NN
l__tasks_item_format_tl
l__tasks_custom_item_format_tl
}
seq_map_inline:Nn l__tasks_seq
{
__tasks_read_item:www ##1 q_stop
bool_if:NTF l__tasks_enumerate_bool
{
tl_if_eq:VnT l__tasks_tmp_label_tl { $tasks$default$label$ }
{
int_gincr:N g__tasks_int
SaveCounterPatternFrom [tasks]
l__tasks_tmpa_tl
l__tasks_label_tl
l__tasks_label_pattern_tl
%-----------------------------------------------------------
% This seems to set @currentlabel globally:
%-----------------------------------------------------------
cs_gset:Npx @currentlabel { l__tasks_label_tl }
%-----------------------------------------------------------
% Carry out the ugly hook hack after setting @currentlabel
% for setting @currentlabel correctly.
% Seems with this package this needs to be done globally,
% thus uglycounterhack does it globally as well.
%-----------------------------------------------------------
l__sillyugly_label_hook_tl
}
}
{
tl_if_blank:VT l__tasks_label_tl
{ tl_set_eq:NN l__tasks_label_tl labelitemi }
}
tl_put_left:NV l__tasks_label_tl l__tasks_label_format_tl
% tl_put_left:NV l__tasks_item_tl l__tasks_item_format_tl
tl_if_eq:VnTF l__tasks_tmp_label_tl { $tasks$default$label$ }
{
__tasks_task:VVV
l__tasks_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
}
{
__tasks_task:VVV
l__tasks_tmp_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
tl_clear:N l__tasks_tmp_label_tl
}
}
}
__tasks_restore_dollar:
ExplSyntaxOff
makeatother
% ====End of patch of tasks.sty====
DeclareExerciseTranslations{answer}{
Fallback = answer ,
English = answer ,
French = r'eponse ,
German = Antwort
}
DeclareExerciseType{question}{
exercise-env = question ,
solution-env = answer ,
exercise-name = XSIMtranslate{question} ,
solution-name = XSIMtranslate{answer} ,
exercise-template = default ,
solution-template = default
}
newcounter{subquestion}[question]
newcounter{subanswer}[answer]
renewcommand*thesubquestion{thequestion.arabic{subquestion}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubquestion{theHquestion.arabic{subquestion}}%
}%
renewcommand*thesubanswer{theanswer.arabic{subanswer}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubanswer{theHanswer.arabic{subanswer}}%
}%
% cleveref-aliases/counter-naming-phrases:
crefname{question}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{answer}{answer}{answers}
crefname{subanswer}{subanswer}{subanswers} % has no effect, obviously
makeatletter
% Why does the tasks-package its own counter-thingie when
% you have to use a counter anyway for getting things
% with label..ref done correctly? This does not make sense to me.
DeclareRobustCommanduglycounterhack[1]{%
refstepcounter{#1}%
globallet@currentlabel=@currentlabel
globalletcref@currentlabel=cref@currentlabel
}%
makeatother
NewTasks[%
%% This will not include the value of the question-counter
%% into the subquestion-items:
%% counter-format = tsk[1]),%
%% This will include the value of the question-counter
%% into the subquestion-items -- I recommend doing this for making
%% references to subquestion-items unambiguous:
counter-format = thequestion.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subquestion},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[%
%% This will not include the value of the answer-counter
%% into the subanswer-items:
%% counter-format = tsk[1]),%
%% This will include the value of the answer-counter
%% into the subanswer-items -- I recommend doing this for making
%% references to subanswer-items unambiguous:
counter-format = theanswer.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subanswer},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subanswerblock}[subanswer](2)
begin{document}
begin{question}[points=3]
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean cref{metawhy}?
end{subquestionblock}
end{question}
begin{answer}[print=true]
begin{subanswerblock}
subanswer! Because isomers are fun. label{because}
subanswer! Because I am funny. label{metabecause}
subanswer! cref{metabecause} is funny but all in all this is no longer funny.
end{subanswerblock}
end{answer}
begin{question}[points=3]
Is there an end to stupid questions? label{stu}
begin{subquestionblock}
subquestion! Discuss why cref{metawhy} is a stupid question but cref{why} is even stupider? label{huh}
subquestion! Are both cref{huh} and cref{metawhy} both stupider that each other?
end{subquestionblock}
end{question}
end{document}
hmmm ... this was lot more complicated than I thought. I really liked the packagestasks
andcleveref
. Thanks for all the effort that you put into helping me out @Ulrich .. I have also written a mail to the package authors.
– magguu
Sep 2 at 12:49
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%2f448667%2fcustom-label-for-references-using-tasks-inside-a-xsim-exercise%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
After trying several things, now I have an ugly hack. It does not solve every thing and introduces some other irritants but it does solve the most vexing counter issue. For this I embed exercise
in a new environment question
which has its own counter called question
. Then the formatting code of subquestion
has a hack to increment another counter called subquestion
.
The end result is that my concern number 2 gets resolved automatically as you can see in the output image attached : the subquestion 3.1 and subquestion 3.3.
However I still cannot resolve concern number 1. I tried to use some other hacks but got embroiled in expandafter
mess. I am not posting those efforts in my MWE here.
Now I have these new concerns:
- How do I get rid of the ")" coming after every references?
- How do I change several invocations of "question" to "subquestion". To wit, "question" in 1.2 should remain unchanged but other "question"s shd change to "subquestion". I could have changed definition of
refsubq
but that would have other problems.
Please see the new MWE::
documentclass[11pt]{article}
usepackage{tasks,cleveref,xsim}
newcommand{refsubq}[1]{cref{#1}.ref{#1}}
newcounter{question}
newcounter{subquestion}[question]
newcommand{uglyhack}{refstepcounter{subquestion}itshape}
NewTasks[counter-format = tsk[1]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[counter-format = tsk[a]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblockA}[subquestion](2)
newenvironment{question}{refstepcounter{question}exercise}{endexercise}
crefname{exercise}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{subquestionblock}{subquestion}{subquestions} % fails
crefname{subquestionblockA}{subquestion}{subquestions} % fails
begin{document}
begin{question}
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean refsubq{metawhy}?
end{subquestionblock}
end{question}
begin{question}
Is there an end to stupid questions? label{stu}
begin{subquestionblockA}
subquestion! Discuss why refsubq{metawhy} is a stupid question but refsubq{why} is even stupider? label{huh}
subquestion! Are refsubq{huh} and refsubq{metawhy} both stupider than each other? label{huh2}
subquestion! Please see refsubq{goto2} for more info. label{goto}
end{subquestionblockA}
end{question}
begin{question}
I am just a question.
begin{subquestionblock}
subquestion! I am a simple subquestion unlike refsubq{huh2}.
subquestion! I am a subquestion (refsubq{self}) stupid enough to refer to myselflabel{self}.
subquestion! Please see refsubq{goto} for even more info. label{goto2}
end{subquestionblock}
end{question}
end{document}
Image ::
add a comment |
After trying several things, now I have an ugly hack. It does not solve every thing and introduces some other irritants but it does solve the most vexing counter issue. For this I embed exercise
in a new environment question
which has its own counter called question
. Then the formatting code of subquestion
has a hack to increment another counter called subquestion
.
The end result is that my concern number 2 gets resolved automatically as you can see in the output image attached : the subquestion 3.1 and subquestion 3.3.
However I still cannot resolve concern number 1. I tried to use some other hacks but got embroiled in expandafter
mess. I am not posting those efforts in my MWE here.
Now I have these new concerns:
- How do I get rid of the ")" coming after every references?
- How do I change several invocations of "question" to "subquestion". To wit, "question" in 1.2 should remain unchanged but other "question"s shd change to "subquestion". I could have changed definition of
refsubq
but that would have other problems.
Please see the new MWE::
documentclass[11pt]{article}
usepackage{tasks,cleveref,xsim}
newcommand{refsubq}[1]{cref{#1}.ref{#1}}
newcounter{question}
newcounter{subquestion}[question]
newcommand{uglyhack}{refstepcounter{subquestion}itshape}
NewTasks[counter-format = tsk[1]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[counter-format = tsk[a]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblockA}[subquestion](2)
newenvironment{question}{refstepcounter{question}exercise}{endexercise}
crefname{exercise}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{subquestionblock}{subquestion}{subquestions} % fails
crefname{subquestionblockA}{subquestion}{subquestions} % fails
begin{document}
begin{question}
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean refsubq{metawhy}?
end{subquestionblock}
end{question}
begin{question}
Is there an end to stupid questions? label{stu}
begin{subquestionblockA}
subquestion! Discuss why refsubq{metawhy} is a stupid question but refsubq{why} is even stupider? label{huh}
subquestion! Are refsubq{huh} and refsubq{metawhy} both stupider than each other? label{huh2}
subquestion! Please see refsubq{goto2} for more info. label{goto}
end{subquestionblockA}
end{question}
begin{question}
I am just a question.
begin{subquestionblock}
subquestion! I am a simple subquestion unlike refsubq{huh2}.
subquestion! I am a subquestion (refsubq{self}) stupid enough to refer to myselflabel{self}.
subquestion! Please see refsubq{goto} for even more info. label{goto2}
end{subquestionblock}
end{question}
end{document}
Image ::
add a comment |
After trying several things, now I have an ugly hack. It does not solve every thing and introduces some other irritants but it does solve the most vexing counter issue. For this I embed exercise
in a new environment question
which has its own counter called question
. Then the formatting code of subquestion
has a hack to increment another counter called subquestion
.
The end result is that my concern number 2 gets resolved automatically as you can see in the output image attached : the subquestion 3.1 and subquestion 3.3.
However I still cannot resolve concern number 1. I tried to use some other hacks but got embroiled in expandafter
mess. I am not posting those efforts in my MWE here.
Now I have these new concerns:
- How do I get rid of the ")" coming after every references?
- How do I change several invocations of "question" to "subquestion". To wit, "question" in 1.2 should remain unchanged but other "question"s shd change to "subquestion". I could have changed definition of
refsubq
but that would have other problems.
Please see the new MWE::
documentclass[11pt]{article}
usepackage{tasks,cleveref,xsim}
newcommand{refsubq}[1]{cref{#1}.ref{#1}}
newcounter{question}
newcounter{subquestion}[question]
newcommand{uglyhack}{refstepcounter{subquestion}itshape}
NewTasks[counter-format = tsk[1]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[counter-format = tsk[a]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblockA}[subquestion](2)
newenvironment{question}{refstepcounter{question}exercise}{endexercise}
crefname{exercise}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{subquestionblock}{subquestion}{subquestions} % fails
crefname{subquestionblockA}{subquestion}{subquestions} % fails
begin{document}
begin{question}
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean refsubq{metawhy}?
end{subquestionblock}
end{question}
begin{question}
Is there an end to stupid questions? label{stu}
begin{subquestionblockA}
subquestion! Discuss why refsubq{metawhy} is a stupid question but refsubq{why} is even stupider? label{huh}
subquestion! Are refsubq{huh} and refsubq{metawhy} both stupider than each other? label{huh2}
subquestion! Please see refsubq{goto2} for more info. label{goto}
end{subquestionblockA}
end{question}
begin{question}
I am just a question.
begin{subquestionblock}
subquestion! I am a simple subquestion unlike refsubq{huh2}.
subquestion! I am a subquestion (refsubq{self}) stupid enough to refer to myselflabel{self}.
subquestion! Please see refsubq{goto} for even more info. label{goto2}
end{subquestionblock}
end{question}
end{document}
Image ::
After trying several things, now I have an ugly hack. It does not solve every thing and introduces some other irritants but it does solve the most vexing counter issue. For this I embed exercise
in a new environment question
which has its own counter called question
. Then the formatting code of subquestion
has a hack to increment another counter called subquestion
.
The end result is that my concern number 2 gets resolved automatically as you can see in the output image attached : the subquestion 3.1 and subquestion 3.3.
However I still cannot resolve concern number 1. I tried to use some other hacks but got embroiled in expandafter
mess. I am not posting those efforts in my MWE here.
Now I have these new concerns:
- How do I get rid of the ")" coming after every references?
- How do I change several invocations of "question" to "subquestion". To wit, "question" in 1.2 should remain unchanged but other "question"s shd change to "subquestion". I could have changed definition of
refsubq
but that would have other problems.
Please see the new MWE::
documentclass[11pt]{article}
usepackage{tasks,cleveref,xsim}
newcommand{refsubq}[1]{cref{#1}.ref{#1}}
newcounter{question}
newcounter{subquestion}[question]
newcommand{uglyhack}{refstepcounter{subquestion}itshape}
NewTasks[counter-format = tsk[1]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[counter-format = tsk[a]),
label-format = uglyhack,%
item-indent = 0em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblockA}[subquestion](2)
newenvironment{question}{refstepcounter{question}exercise}{endexercise}
crefname{exercise}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{subquestionblock}{subquestion}{subquestions} % fails
crefname{subquestionblockA}{subquestion}{subquestions} % fails
begin{document}
begin{question}
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean refsubq{metawhy}?
end{subquestionblock}
end{question}
begin{question}
Is there an end to stupid questions? label{stu}
begin{subquestionblockA}
subquestion! Discuss why refsubq{metawhy} is a stupid question but refsubq{why} is even stupider? label{huh}
subquestion! Are refsubq{huh} and refsubq{metawhy} both stupider than each other? label{huh2}
subquestion! Please see refsubq{goto2} for more info. label{goto}
end{subquestionblockA}
end{question}
begin{question}
I am just a question.
begin{subquestionblock}
subquestion! I am a simple subquestion unlike refsubq{huh2}.
subquestion! I am a subquestion (refsubq{self}) stupid enough to refer to myselflabel{self}.
subquestion! Please see refsubq{goto} for even more info. label{goto2}
end{subquestionblock}
end{question}
end{document}
Image ::
answered Sep 4 at 6:46
magguu
37617
37617
add a comment |
add a comment |
Address your request to the author of the tasks-package and make a bug report:
The code of the tasks package comes without properly commented sources, just as a .sty-file and thus is inscrutable. Same for some of the packages loaded/used by the tasks-package.
It seems that instead of using
refstepcounter
, the author of that package does his own counter-thingies, based on expl3 and using yet another one of his packages, calledcntformats
, which one has to spend hours on studying for finding out what might probably go on. According to my opinion, all this makes things even more inscrutable and, according to my opinion, is definitely not a good idea if one wishes ones own things to properly interact with common LaTeX2e-infrastructure.
Within that inscrutable package,
cs_gset:Npx
is used for defining the macro@currentlabel
. Seems this does redefine@currentlabel
globally. The LaTeX2e-kernel does never redefine@currentlabel
globally. If you do so, placing labels after ending one of thosetasks
-environments will yield wrong numbers when referencing these labels.
(Well, the
hyperref
-package does redefine@currentHref
globally, which in my opinion is a similar well-established mis-concept as it may lead to connecting references with hyperlinks to wrong targets.)
This sort of things does confuse and scare off those LaTeX-beginners who exercise the care of checking the correctness of the result while not being experienced enough for tracking down what is happening when things do not turn out correct. I saw users despairing after spending hours and days on studying inscrutable code instead of learning the relevant basics of their field of study as they were, while not yet knowing anything about these things, urged by teachers, who found another way of living out their profile neurosis, to use LaTeX and specific packages, which altogether they would never ever need again after leaving school/university.
You additionally use the package
cleveref
. This package does redefine some of the kernel-macros, e.g.,refstepcounter
and does rely on people using standard-infrastructure for doing counter-thingies, which thetasks
-package does not:
cleveref
does redefinerefstepcounter
to also define an additional macrocref@currentlabel
and does redefinelabel
to write twonewlabel
-entries to the .aux-file instead of one: The usualnewlabel
-entry whose data stems from@currentlabel
and an additionalnewlabel
-entry where the label-name has the suffix@cref
and whose data stems fromcref@currentlabel
and which delivers the data needed additionally by thecleveref
-referencing-macros.
The
tasks
-package, which does its own counter-thingies and which does redefine@currentlabel
on its own instead of using LaTeX2e-infrastructure/refstepcounter
, does not setcref@currentlabel
and thus breaks, e.g., thecleveref
package.
Inspired by your own answer/your hack I just came up with a variant where you get rid of the closing parenthese and which makes cref
possible also and which also works out when using the hyperref package.
Of course my variant does not resolve the tasks package's behavior of redefining @currentlabel
globally but does the same thing for cleveref's cref@currentlabel
.
The gist is:
I added another key "ugly-label-hook" to the tasks-package which lets you specify some tokens that get inserted whenever the tasks-package for one of its items modifies @currentlabel
.
You can use this hook for "refstepping" the "dummy"-counter for your subquestions/subanswers.
"refstepping" the "dummy"-counter makes sure the macros @currentlabel
and cref@currentlabel
are (re)defined correctly.
As the tasks-package does for whatever reason redefine @currentlabel
globally, with the "ugly-label-hook" it must be ensured that both @currentlabel
and cref@currentlabel
are (re)defined globally also.
documentclass[11pt]{article}
usepackage{hyperref}
usepackage{tasks,cleveref,xsim}
% ====Begin of patch of tasks.sty====
makeatletter
ExplSyntaxOn
% Allocate another token list for the ugly hack:
tl_new:N l__sillyugly_label_hook_tl
% Add a key "ugly-label-hook" for setting that
% token list:
keys_define:nn {tasks/list}
{
ugly-label-hook .tl_set:N = l__sillyugly_label_hook_tl ,
}
% Include the ugly-label-hook-key into the `tasks' object:
% #1: number of items
% #2: number of columns
% #3: label-format
DeclareObjectType {tasks} {3}
% the `default' template interface:
DeclareTemplateInterface {tasks} {default} {3}
{
enumerate : boolean = true ,
label : tokenlist ,
indent : length = 2.5em ,
counter-format : tokenlist = tsk[a]) ,
label-format : tokenlist ,
%----------------------------------------------------
ugly-label-hook : tokenlist ,
%----------------------------------------------------
label-width : length = 1em ,
label-offset : length = .3333em ,
item-format : tokenlist ,
after-item-skip : skip = 1ex plus 1ex minus 1ex
}
% When patching the next macro, the really unlikely marker $ with
% unusual catcode is used in ``$tasks$default$label$'':
cs_set:Nx __tasks_restore_dollar:
{ char_set_catcode:nn {36} { char_value_catcode:n {36} } }
char_set_catcode_alignment:N $
% Include the ugly-label-hook-key into the `default' template code
% and apply the hook when @currentlabel is changed:
DeclareTemplateCode {tasks} {default} {3}
{
enumerate = l__tasks_enumerate_bool ,
label = l__tasks_label_tl ,
indent = l__tasks_item_default_indent_dim ,
counter-format = l__tasks_label_pattern_tl ,
label-format = l__tasks_label_format_tl ,
%----------------------------------------------------
ugly-label-hook = l__sillyugly_label_hook_tl ,
%----------------------------------------------------
label-width = l__tasks_label_default_width_dim ,
label-offset = l__tasks_label_default_offset_dim ,
item-format = l__tasks_item_format_tl ,
after-item-skip = l__tasks_after_item_skip
}
{
AssignTemplateKeys
bool_if:NF l__tasks_label_width_bool
{
dim_set_eq:NN
l__tasks_label_width_dim
l__tasks_label_default_width_dim
}
bool_if:NF l__tasks_item_indent_bool
{
dim_set_eq:NN
l__tasks_item_indent_dim
l__tasks_item_default_indent_dim
}
bool_if:NF l__tasks_label_offset_bool
{
dim_set_eq:NN
l__tasks_label_offset_dim
l__tasks_label_default_offset_dim
}
% dim_compare:nNnT
% { l__tasks_item_indent_dim }
% <
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% {
% dim_set:Nn l__tasks_item_indent_dim
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% }
bool_if:NT l__tasks_custom_after_item_skip_bool
{
skip_set_eq:NN
l__tasks_after_item_skip
l__tasks_custom_after_item_skip
}
bool_if:NT l__tasks_custom_label_bool
{
tl_set_eq:NN
l__tasks_label_tl
l__tasks_custom_label_tl
bool_set_false:N l__tasks_enumerate_bool
}
__tasks_label_align:V l__tasks_label_align_tl
% need this for enumerate list:
bool_if:nT { !l__tasks_resume_bool && l__tasks_enumerate_bool }
{ int_gzero:N g__tasks_int }
int_set:Nn l__tasks_columns_int {#2}
% set all the items in their own coffins and join with the ground:
int_gzero:N g__tasks_current_col_num_int
int_set:Nn g__tasks_current_row_num_int {1}
tl_if_blank:VF l__tasks_custom_label_pattern_tl
{
tl_set_eq:NN
l__tasks_label_pattern_tl
l__tasks_custom_label_pattern_tl
}
tl_if_blank:VF l__tasks_custom_label_format_tl
{
tl_set_eq:NN
l__tasks_label_format_tl
l__tasks_custom_label_format_tl
}
tl_if_blank:VF l__tasks_custom_item_format_tl
{
tl_set_eq:NN
l__tasks_item_format_tl
l__tasks_custom_item_format_tl
}
seq_map_inline:Nn l__tasks_seq
{
__tasks_read_item:www ##1 q_stop
bool_if:NTF l__tasks_enumerate_bool
{
tl_if_eq:VnT l__tasks_tmp_label_tl { $tasks$default$label$ }
{
int_gincr:N g__tasks_int
SaveCounterPatternFrom [tasks]
l__tasks_tmpa_tl
l__tasks_label_tl
l__tasks_label_pattern_tl
%-----------------------------------------------------------
% This seems to set @currentlabel globally:
%-----------------------------------------------------------
cs_gset:Npx @currentlabel { l__tasks_label_tl }
%-----------------------------------------------------------
% Carry out the ugly hook hack after setting @currentlabel
% for setting @currentlabel correctly.
% Seems with this package this needs to be done globally,
% thus uglycounterhack does it globally as well.
%-----------------------------------------------------------
l__sillyugly_label_hook_tl
}
}
{
tl_if_blank:VT l__tasks_label_tl
{ tl_set_eq:NN l__tasks_label_tl labelitemi }
}
tl_put_left:NV l__tasks_label_tl l__tasks_label_format_tl
% tl_put_left:NV l__tasks_item_tl l__tasks_item_format_tl
tl_if_eq:VnTF l__tasks_tmp_label_tl { $tasks$default$label$ }
{
__tasks_task:VVV
l__tasks_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
}
{
__tasks_task:VVV
l__tasks_tmp_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
tl_clear:N l__tasks_tmp_label_tl
}
}
}
__tasks_restore_dollar:
ExplSyntaxOff
makeatother
% ====End of patch of tasks.sty====
DeclareExerciseTranslations{answer}{
Fallback = answer ,
English = answer ,
French = r'eponse ,
German = Antwort
}
DeclareExerciseType{question}{
exercise-env = question ,
solution-env = answer ,
exercise-name = XSIMtranslate{question} ,
solution-name = XSIMtranslate{answer} ,
exercise-template = default ,
solution-template = default
}
newcounter{subquestion}[question]
newcounter{subanswer}[answer]
renewcommand*thesubquestion{thequestion.arabic{subquestion}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubquestion{theHquestion.arabic{subquestion}}%
}%
renewcommand*thesubanswer{theanswer.arabic{subanswer}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubanswer{theHanswer.arabic{subanswer}}%
}%
% cleveref-aliases/counter-naming-phrases:
crefname{question}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{answer}{answer}{answers}
crefname{subanswer}{subanswer}{subanswers} % has no effect, obviously
makeatletter
% Why does the tasks-package its own counter-thingie when
% you have to use a counter anyway for getting things
% with label..ref done correctly? This does not make sense to me.
DeclareRobustCommanduglycounterhack[1]{%
refstepcounter{#1}%
globallet@currentlabel=@currentlabel
globalletcref@currentlabel=cref@currentlabel
}%
makeatother
NewTasks[%
%% This will not include the value of the question-counter
%% into the subquestion-items:
%% counter-format = tsk[1]),%
%% This will include the value of the question-counter
%% into the subquestion-items -- I recommend doing this for making
%% references to subquestion-items unambiguous:
counter-format = thequestion.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subquestion},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[%
%% This will not include the value of the answer-counter
%% into the subanswer-items:
%% counter-format = tsk[1]),%
%% This will include the value of the answer-counter
%% into the subanswer-items -- I recommend doing this for making
%% references to subanswer-items unambiguous:
counter-format = theanswer.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subanswer},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subanswerblock}[subanswer](2)
begin{document}
begin{question}[points=3]
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean cref{metawhy}?
end{subquestionblock}
end{question}
begin{answer}[print=true]
begin{subanswerblock}
subanswer! Because isomers are fun. label{because}
subanswer! Because I am funny. label{metabecause}
subanswer! cref{metabecause} is funny but all in all this is no longer funny.
end{subanswerblock}
end{answer}
begin{question}[points=3]
Is there an end to stupid questions? label{stu}
begin{subquestionblock}
subquestion! Discuss why cref{metawhy} is a stupid question but cref{why} is even stupider? label{huh}
subquestion! Are both cref{huh} and cref{metawhy} both stupider that each other?
end{subquestionblock}
end{question}
end{document}
hmmm ... this was lot more complicated than I thought. I really liked the packagestasks
andcleveref
. Thanks for all the effort that you put into helping me out @Ulrich .. I have also written a mail to the package authors.
– magguu
Sep 2 at 12:49
add a comment |
Address your request to the author of the tasks-package and make a bug report:
The code of the tasks package comes without properly commented sources, just as a .sty-file and thus is inscrutable. Same for some of the packages loaded/used by the tasks-package.
It seems that instead of using
refstepcounter
, the author of that package does his own counter-thingies, based on expl3 and using yet another one of his packages, calledcntformats
, which one has to spend hours on studying for finding out what might probably go on. According to my opinion, all this makes things even more inscrutable and, according to my opinion, is definitely not a good idea if one wishes ones own things to properly interact with common LaTeX2e-infrastructure.
Within that inscrutable package,
cs_gset:Npx
is used for defining the macro@currentlabel
. Seems this does redefine@currentlabel
globally. The LaTeX2e-kernel does never redefine@currentlabel
globally. If you do so, placing labels after ending one of thosetasks
-environments will yield wrong numbers when referencing these labels.
(Well, the
hyperref
-package does redefine@currentHref
globally, which in my opinion is a similar well-established mis-concept as it may lead to connecting references with hyperlinks to wrong targets.)
This sort of things does confuse and scare off those LaTeX-beginners who exercise the care of checking the correctness of the result while not being experienced enough for tracking down what is happening when things do not turn out correct. I saw users despairing after spending hours and days on studying inscrutable code instead of learning the relevant basics of their field of study as they were, while not yet knowing anything about these things, urged by teachers, who found another way of living out their profile neurosis, to use LaTeX and specific packages, which altogether they would never ever need again after leaving school/university.
You additionally use the package
cleveref
. This package does redefine some of the kernel-macros, e.g.,refstepcounter
and does rely on people using standard-infrastructure for doing counter-thingies, which thetasks
-package does not:
cleveref
does redefinerefstepcounter
to also define an additional macrocref@currentlabel
and does redefinelabel
to write twonewlabel
-entries to the .aux-file instead of one: The usualnewlabel
-entry whose data stems from@currentlabel
and an additionalnewlabel
-entry where the label-name has the suffix@cref
and whose data stems fromcref@currentlabel
and which delivers the data needed additionally by thecleveref
-referencing-macros.
The
tasks
-package, which does its own counter-thingies and which does redefine@currentlabel
on its own instead of using LaTeX2e-infrastructure/refstepcounter
, does not setcref@currentlabel
and thus breaks, e.g., thecleveref
package.
Inspired by your own answer/your hack I just came up with a variant where you get rid of the closing parenthese and which makes cref
possible also and which also works out when using the hyperref package.
Of course my variant does not resolve the tasks package's behavior of redefining @currentlabel
globally but does the same thing for cleveref's cref@currentlabel
.
The gist is:
I added another key "ugly-label-hook" to the tasks-package which lets you specify some tokens that get inserted whenever the tasks-package for one of its items modifies @currentlabel
.
You can use this hook for "refstepping" the "dummy"-counter for your subquestions/subanswers.
"refstepping" the "dummy"-counter makes sure the macros @currentlabel
and cref@currentlabel
are (re)defined correctly.
As the tasks-package does for whatever reason redefine @currentlabel
globally, with the "ugly-label-hook" it must be ensured that both @currentlabel
and cref@currentlabel
are (re)defined globally also.
documentclass[11pt]{article}
usepackage{hyperref}
usepackage{tasks,cleveref,xsim}
% ====Begin of patch of tasks.sty====
makeatletter
ExplSyntaxOn
% Allocate another token list for the ugly hack:
tl_new:N l__sillyugly_label_hook_tl
% Add a key "ugly-label-hook" for setting that
% token list:
keys_define:nn {tasks/list}
{
ugly-label-hook .tl_set:N = l__sillyugly_label_hook_tl ,
}
% Include the ugly-label-hook-key into the `tasks' object:
% #1: number of items
% #2: number of columns
% #3: label-format
DeclareObjectType {tasks} {3}
% the `default' template interface:
DeclareTemplateInterface {tasks} {default} {3}
{
enumerate : boolean = true ,
label : tokenlist ,
indent : length = 2.5em ,
counter-format : tokenlist = tsk[a]) ,
label-format : tokenlist ,
%----------------------------------------------------
ugly-label-hook : tokenlist ,
%----------------------------------------------------
label-width : length = 1em ,
label-offset : length = .3333em ,
item-format : tokenlist ,
after-item-skip : skip = 1ex plus 1ex minus 1ex
}
% When patching the next macro, the really unlikely marker $ with
% unusual catcode is used in ``$tasks$default$label$'':
cs_set:Nx __tasks_restore_dollar:
{ char_set_catcode:nn {36} { char_value_catcode:n {36} } }
char_set_catcode_alignment:N $
% Include the ugly-label-hook-key into the `default' template code
% and apply the hook when @currentlabel is changed:
DeclareTemplateCode {tasks} {default} {3}
{
enumerate = l__tasks_enumerate_bool ,
label = l__tasks_label_tl ,
indent = l__tasks_item_default_indent_dim ,
counter-format = l__tasks_label_pattern_tl ,
label-format = l__tasks_label_format_tl ,
%----------------------------------------------------
ugly-label-hook = l__sillyugly_label_hook_tl ,
%----------------------------------------------------
label-width = l__tasks_label_default_width_dim ,
label-offset = l__tasks_label_default_offset_dim ,
item-format = l__tasks_item_format_tl ,
after-item-skip = l__tasks_after_item_skip
}
{
AssignTemplateKeys
bool_if:NF l__tasks_label_width_bool
{
dim_set_eq:NN
l__tasks_label_width_dim
l__tasks_label_default_width_dim
}
bool_if:NF l__tasks_item_indent_bool
{
dim_set_eq:NN
l__tasks_item_indent_dim
l__tasks_item_default_indent_dim
}
bool_if:NF l__tasks_label_offset_bool
{
dim_set_eq:NN
l__tasks_label_offset_dim
l__tasks_label_default_offset_dim
}
% dim_compare:nNnT
% { l__tasks_item_indent_dim }
% <
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% {
% dim_set:Nn l__tasks_item_indent_dim
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% }
bool_if:NT l__tasks_custom_after_item_skip_bool
{
skip_set_eq:NN
l__tasks_after_item_skip
l__tasks_custom_after_item_skip
}
bool_if:NT l__tasks_custom_label_bool
{
tl_set_eq:NN
l__tasks_label_tl
l__tasks_custom_label_tl
bool_set_false:N l__tasks_enumerate_bool
}
__tasks_label_align:V l__tasks_label_align_tl
% need this for enumerate list:
bool_if:nT { !l__tasks_resume_bool && l__tasks_enumerate_bool }
{ int_gzero:N g__tasks_int }
int_set:Nn l__tasks_columns_int {#2}
% set all the items in their own coffins and join with the ground:
int_gzero:N g__tasks_current_col_num_int
int_set:Nn g__tasks_current_row_num_int {1}
tl_if_blank:VF l__tasks_custom_label_pattern_tl
{
tl_set_eq:NN
l__tasks_label_pattern_tl
l__tasks_custom_label_pattern_tl
}
tl_if_blank:VF l__tasks_custom_label_format_tl
{
tl_set_eq:NN
l__tasks_label_format_tl
l__tasks_custom_label_format_tl
}
tl_if_blank:VF l__tasks_custom_item_format_tl
{
tl_set_eq:NN
l__tasks_item_format_tl
l__tasks_custom_item_format_tl
}
seq_map_inline:Nn l__tasks_seq
{
__tasks_read_item:www ##1 q_stop
bool_if:NTF l__tasks_enumerate_bool
{
tl_if_eq:VnT l__tasks_tmp_label_tl { $tasks$default$label$ }
{
int_gincr:N g__tasks_int
SaveCounterPatternFrom [tasks]
l__tasks_tmpa_tl
l__tasks_label_tl
l__tasks_label_pattern_tl
%-----------------------------------------------------------
% This seems to set @currentlabel globally:
%-----------------------------------------------------------
cs_gset:Npx @currentlabel { l__tasks_label_tl }
%-----------------------------------------------------------
% Carry out the ugly hook hack after setting @currentlabel
% for setting @currentlabel correctly.
% Seems with this package this needs to be done globally,
% thus uglycounterhack does it globally as well.
%-----------------------------------------------------------
l__sillyugly_label_hook_tl
}
}
{
tl_if_blank:VT l__tasks_label_tl
{ tl_set_eq:NN l__tasks_label_tl labelitemi }
}
tl_put_left:NV l__tasks_label_tl l__tasks_label_format_tl
% tl_put_left:NV l__tasks_item_tl l__tasks_item_format_tl
tl_if_eq:VnTF l__tasks_tmp_label_tl { $tasks$default$label$ }
{
__tasks_task:VVV
l__tasks_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
}
{
__tasks_task:VVV
l__tasks_tmp_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
tl_clear:N l__tasks_tmp_label_tl
}
}
}
__tasks_restore_dollar:
ExplSyntaxOff
makeatother
% ====End of patch of tasks.sty====
DeclareExerciseTranslations{answer}{
Fallback = answer ,
English = answer ,
French = r'eponse ,
German = Antwort
}
DeclareExerciseType{question}{
exercise-env = question ,
solution-env = answer ,
exercise-name = XSIMtranslate{question} ,
solution-name = XSIMtranslate{answer} ,
exercise-template = default ,
solution-template = default
}
newcounter{subquestion}[question]
newcounter{subanswer}[answer]
renewcommand*thesubquestion{thequestion.arabic{subquestion}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubquestion{theHquestion.arabic{subquestion}}%
}%
renewcommand*thesubanswer{theanswer.arabic{subanswer}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubanswer{theHanswer.arabic{subanswer}}%
}%
% cleveref-aliases/counter-naming-phrases:
crefname{question}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{answer}{answer}{answers}
crefname{subanswer}{subanswer}{subanswers} % has no effect, obviously
makeatletter
% Why does the tasks-package its own counter-thingie when
% you have to use a counter anyway for getting things
% with label..ref done correctly? This does not make sense to me.
DeclareRobustCommanduglycounterhack[1]{%
refstepcounter{#1}%
globallet@currentlabel=@currentlabel
globalletcref@currentlabel=cref@currentlabel
}%
makeatother
NewTasks[%
%% This will not include the value of the question-counter
%% into the subquestion-items:
%% counter-format = tsk[1]),%
%% This will include the value of the question-counter
%% into the subquestion-items -- I recommend doing this for making
%% references to subquestion-items unambiguous:
counter-format = thequestion.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subquestion},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[%
%% This will not include the value of the answer-counter
%% into the subanswer-items:
%% counter-format = tsk[1]),%
%% This will include the value of the answer-counter
%% into the subanswer-items -- I recommend doing this for making
%% references to subanswer-items unambiguous:
counter-format = theanswer.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subanswer},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subanswerblock}[subanswer](2)
begin{document}
begin{question}[points=3]
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean cref{metawhy}?
end{subquestionblock}
end{question}
begin{answer}[print=true]
begin{subanswerblock}
subanswer! Because isomers are fun. label{because}
subanswer! Because I am funny. label{metabecause}
subanswer! cref{metabecause} is funny but all in all this is no longer funny.
end{subanswerblock}
end{answer}
begin{question}[points=3]
Is there an end to stupid questions? label{stu}
begin{subquestionblock}
subquestion! Discuss why cref{metawhy} is a stupid question but cref{why} is even stupider? label{huh}
subquestion! Are both cref{huh} and cref{metawhy} both stupider that each other?
end{subquestionblock}
end{question}
end{document}
hmmm ... this was lot more complicated than I thought. I really liked the packagestasks
andcleveref
. Thanks for all the effort that you put into helping me out @Ulrich .. I have also written a mail to the package authors.
– magguu
Sep 2 at 12:49
add a comment |
Address your request to the author of the tasks-package and make a bug report:
The code of the tasks package comes without properly commented sources, just as a .sty-file and thus is inscrutable. Same for some of the packages loaded/used by the tasks-package.
It seems that instead of using
refstepcounter
, the author of that package does his own counter-thingies, based on expl3 and using yet another one of his packages, calledcntformats
, which one has to spend hours on studying for finding out what might probably go on. According to my opinion, all this makes things even more inscrutable and, according to my opinion, is definitely not a good idea if one wishes ones own things to properly interact with common LaTeX2e-infrastructure.
Within that inscrutable package,
cs_gset:Npx
is used for defining the macro@currentlabel
. Seems this does redefine@currentlabel
globally. The LaTeX2e-kernel does never redefine@currentlabel
globally. If you do so, placing labels after ending one of thosetasks
-environments will yield wrong numbers when referencing these labels.
(Well, the
hyperref
-package does redefine@currentHref
globally, which in my opinion is a similar well-established mis-concept as it may lead to connecting references with hyperlinks to wrong targets.)
This sort of things does confuse and scare off those LaTeX-beginners who exercise the care of checking the correctness of the result while not being experienced enough for tracking down what is happening when things do not turn out correct. I saw users despairing after spending hours and days on studying inscrutable code instead of learning the relevant basics of their field of study as they were, while not yet knowing anything about these things, urged by teachers, who found another way of living out their profile neurosis, to use LaTeX and specific packages, which altogether they would never ever need again after leaving school/university.
You additionally use the package
cleveref
. This package does redefine some of the kernel-macros, e.g.,refstepcounter
and does rely on people using standard-infrastructure for doing counter-thingies, which thetasks
-package does not:
cleveref
does redefinerefstepcounter
to also define an additional macrocref@currentlabel
and does redefinelabel
to write twonewlabel
-entries to the .aux-file instead of one: The usualnewlabel
-entry whose data stems from@currentlabel
and an additionalnewlabel
-entry where the label-name has the suffix@cref
and whose data stems fromcref@currentlabel
and which delivers the data needed additionally by thecleveref
-referencing-macros.
The
tasks
-package, which does its own counter-thingies and which does redefine@currentlabel
on its own instead of using LaTeX2e-infrastructure/refstepcounter
, does not setcref@currentlabel
and thus breaks, e.g., thecleveref
package.
Inspired by your own answer/your hack I just came up with a variant where you get rid of the closing parenthese and which makes cref
possible also and which also works out when using the hyperref package.
Of course my variant does not resolve the tasks package's behavior of redefining @currentlabel
globally but does the same thing for cleveref's cref@currentlabel
.
The gist is:
I added another key "ugly-label-hook" to the tasks-package which lets you specify some tokens that get inserted whenever the tasks-package for one of its items modifies @currentlabel
.
You can use this hook for "refstepping" the "dummy"-counter for your subquestions/subanswers.
"refstepping" the "dummy"-counter makes sure the macros @currentlabel
and cref@currentlabel
are (re)defined correctly.
As the tasks-package does for whatever reason redefine @currentlabel
globally, with the "ugly-label-hook" it must be ensured that both @currentlabel
and cref@currentlabel
are (re)defined globally also.
documentclass[11pt]{article}
usepackage{hyperref}
usepackage{tasks,cleveref,xsim}
% ====Begin of patch of tasks.sty====
makeatletter
ExplSyntaxOn
% Allocate another token list for the ugly hack:
tl_new:N l__sillyugly_label_hook_tl
% Add a key "ugly-label-hook" for setting that
% token list:
keys_define:nn {tasks/list}
{
ugly-label-hook .tl_set:N = l__sillyugly_label_hook_tl ,
}
% Include the ugly-label-hook-key into the `tasks' object:
% #1: number of items
% #2: number of columns
% #3: label-format
DeclareObjectType {tasks} {3}
% the `default' template interface:
DeclareTemplateInterface {tasks} {default} {3}
{
enumerate : boolean = true ,
label : tokenlist ,
indent : length = 2.5em ,
counter-format : tokenlist = tsk[a]) ,
label-format : tokenlist ,
%----------------------------------------------------
ugly-label-hook : tokenlist ,
%----------------------------------------------------
label-width : length = 1em ,
label-offset : length = .3333em ,
item-format : tokenlist ,
after-item-skip : skip = 1ex plus 1ex minus 1ex
}
% When patching the next macro, the really unlikely marker $ with
% unusual catcode is used in ``$tasks$default$label$'':
cs_set:Nx __tasks_restore_dollar:
{ char_set_catcode:nn {36} { char_value_catcode:n {36} } }
char_set_catcode_alignment:N $
% Include the ugly-label-hook-key into the `default' template code
% and apply the hook when @currentlabel is changed:
DeclareTemplateCode {tasks} {default} {3}
{
enumerate = l__tasks_enumerate_bool ,
label = l__tasks_label_tl ,
indent = l__tasks_item_default_indent_dim ,
counter-format = l__tasks_label_pattern_tl ,
label-format = l__tasks_label_format_tl ,
%----------------------------------------------------
ugly-label-hook = l__sillyugly_label_hook_tl ,
%----------------------------------------------------
label-width = l__tasks_label_default_width_dim ,
label-offset = l__tasks_label_default_offset_dim ,
item-format = l__tasks_item_format_tl ,
after-item-skip = l__tasks_after_item_skip
}
{
AssignTemplateKeys
bool_if:NF l__tasks_label_width_bool
{
dim_set_eq:NN
l__tasks_label_width_dim
l__tasks_label_default_width_dim
}
bool_if:NF l__tasks_item_indent_bool
{
dim_set_eq:NN
l__tasks_item_indent_dim
l__tasks_item_default_indent_dim
}
bool_if:NF l__tasks_label_offset_bool
{
dim_set_eq:NN
l__tasks_label_offset_dim
l__tasks_label_default_offset_dim
}
% dim_compare:nNnT
% { l__tasks_item_indent_dim }
% <
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% {
% dim_set:Nn l__tasks_item_indent_dim
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% }
bool_if:NT l__tasks_custom_after_item_skip_bool
{
skip_set_eq:NN
l__tasks_after_item_skip
l__tasks_custom_after_item_skip
}
bool_if:NT l__tasks_custom_label_bool
{
tl_set_eq:NN
l__tasks_label_tl
l__tasks_custom_label_tl
bool_set_false:N l__tasks_enumerate_bool
}
__tasks_label_align:V l__tasks_label_align_tl
% need this for enumerate list:
bool_if:nT { !l__tasks_resume_bool && l__tasks_enumerate_bool }
{ int_gzero:N g__tasks_int }
int_set:Nn l__tasks_columns_int {#2}
% set all the items in their own coffins and join with the ground:
int_gzero:N g__tasks_current_col_num_int
int_set:Nn g__tasks_current_row_num_int {1}
tl_if_blank:VF l__tasks_custom_label_pattern_tl
{
tl_set_eq:NN
l__tasks_label_pattern_tl
l__tasks_custom_label_pattern_tl
}
tl_if_blank:VF l__tasks_custom_label_format_tl
{
tl_set_eq:NN
l__tasks_label_format_tl
l__tasks_custom_label_format_tl
}
tl_if_blank:VF l__tasks_custom_item_format_tl
{
tl_set_eq:NN
l__tasks_item_format_tl
l__tasks_custom_item_format_tl
}
seq_map_inline:Nn l__tasks_seq
{
__tasks_read_item:www ##1 q_stop
bool_if:NTF l__tasks_enumerate_bool
{
tl_if_eq:VnT l__tasks_tmp_label_tl { $tasks$default$label$ }
{
int_gincr:N g__tasks_int
SaveCounterPatternFrom [tasks]
l__tasks_tmpa_tl
l__tasks_label_tl
l__tasks_label_pattern_tl
%-----------------------------------------------------------
% This seems to set @currentlabel globally:
%-----------------------------------------------------------
cs_gset:Npx @currentlabel { l__tasks_label_tl }
%-----------------------------------------------------------
% Carry out the ugly hook hack after setting @currentlabel
% for setting @currentlabel correctly.
% Seems with this package this needs to be done globally,
% thus uglycounterhack does it globally as well.
%-----------------------------------------------------------
l__sillyugly_label_hook_tl
}
}
{
tl_if_blank:VT l__tasks_label_tl
{ tl_set_eq:NN l__tasks_label_tl labelitemi }
}
tl_put_left:NV l__tasks_label_tl l__tasks_label_format_tl
% tl_put_left:NV l__tasks_item_tl l__tasks_item_format_tl
tl_if_eq:VnTF l__tasks_tmp_label_tl { $tasks$default$label$ }
{
__tasks_task:VVV
l__tasks_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
}
{
__tasks_task:VVV
l__tasks_tmp_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
tl_clear:N l__tasks_tmp_label_tl
}
}
}
__tasks_restore_dollar:
ExplSyntaxOff
makeatother
% ====End of patch of tasks.sty====
DeclareExerciseTranslations{answer}{
Fallback = answer ,
English = answer ,
French = r'eponse ,
German = Antwort
}
DeclareExerciseType{question}{
exercise-env = question ,
solution-env = answer ,
exercise-name = XSIMtranslate{question} ,
solution-name = XSIMtranslate{answer} ,
exercise-template = default ,
solution-template = default
}
newcounter{subquestion}[question]
newcounter{subanswer}[answer]
renewcommand*thesubquestion{thequestion.arabic{subquestion}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubquestion{theHquestion.arabic{subquestion}}%
}%
renewcommand*thesubanswer{theanswer.arabic{subanswer}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubanswer{theHanswer.arabic{subanswer}}%
}%
% cleveref-aliases/counter-naming-phrases:
crefname{question}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{answer}{answer}{answers}
crefname{subanswer}{subanswer}{subanswers} % has no effect, obviously
makeatletter
% Why does the tasks-package its own counter-thingie when
% you have to use a counter anyway for getting things
% with label..ref done correctly? This does not make sense to me.
DeclareRobustCommanduglycounterhack[1]{%
refstepcounter{#1}%
globallet@currentlabel=@currentlabel
globalletcref@currentlabel=cref@currentlabel
}%
makeatother
NewTasks[%
%% This will not include the value of the question-counter
%% into the subquestion-items:
%% counter-format = tsk[1]),%
%% This will include the value of the question-counter
%% into the subquestion-items -- I recommend doing this for making
%% references to subquestion-items unambiguous:
counter-format = thequestion.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subquestion},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[%
%% This will not include the value of the answer-counter
%% into the subanswer-items:
%% counter-format = tsk[1]),%
%% This will include the value of the answer-counter
%% into the subanswer-items -- I recommend doing this for making
%% references to subanswer-items unambiguous:
counter-format = theanswer.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subanswer},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subanswerblock}[subanswer](2)
begin{document}
begin{question}[points=3]
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean cref{metawhy}?
end{subquestionblock}
end{question}
begin{answer}[print=true]
begin{subanswerblock}
subanswer! Because isomers are fun. label{because}
subanswer! Because I am funny. label{metabecause}
subanswer! cref{metabecause} is funny but all in all this is no longer funny.
end{subanswerblock}
end{answer}
begin{question}[points=3]
Is there an end to stupid questions? label{stu}
begin{subquestionblock}
subquestion! Discuss why cref{metawhy} is a stupid question but cref{why} is even stupider? label{huh}
subquestion! Are both cref{huh} and cref{metawhy} both stupider that each other?
end{subquestionblock}
end{question}
end{document}
Address your request to the author of the tasks-package and make a bug report:
The code of the tasks package comes without properly commented sources, just as a .sty-file and thus is inscrutable. Same for some of the packages loaded/used by the tasks-package.
It seems that instead of using
refstepcounter
, the author of that package does his own counter-thingies, based on expl3 and using yet another one of his packages, calledcntformats
, which one has to spend hours on studying for finding out what might probably go on. According to my opinion, all this makes things even more inscrutable and, according to my opinion, is definitely not a good idea if one wishes ones own things to properly interact with common LaTeX2e-infrastructure.
Within that inscrutable package,
cs_gset:Npx
is used for defining the macro@currentlabel
. Seems this does redefine@currentlabel
globally. The LaTeX2e-kernel does never redefine@currentlabel
globally. If you do so, placing labels after ending one of thosetasks
-environments will yield wrong numbers when referencing these labels.
(Well, the
hyperref
-package does redefine@currentHref
globally, which in my opinion is a similar well-established mis-concept as it may lead to connecting references with hyperlinks to wrong targets.)
This sort of things does confuse and scare off those LaTeX-beginners who exercise the care of checking the correctness of the result while not being experienced enough for tracking down what is happening when things do not turn out correct. I saw users despairing after spending hours and days on studying inscrutable code instead of learning the relevant basics of their field of study as they were, while not yet knowing anything about these things, urged by teachers, who found another way of living out their profile neurosis, to use LaTeX and specific packages, which altogether they would never ever need again after leaving school/university.
You additionally use the package
cleveref
. This package does redefine some of the kernel-macros, e.g.,refstepcounter
and does rely on people using standard-infrastructure for doing counter-thingies, which thetasks
-package does not:
cleveref
does redefinerefstepcounter
to also define an additional macrocref@currentlabel
and does redefinelabel
to write twonewlabel
-entries to the .aux-file instead of one: The usualnewlabel
-entry whose data stems from@currentlabel
and an additionalnewlabel
-entry where the label-name has the suffix@cref
and whose data stems fromcref@currentlabel
and which delivers the data needed additionally by thecleveref
-referencing-macros.
The
tasks
-package, which does its own counter-thingies and which does redefine@currentlabel
on its own instead of using LaTeX2e-infrastructure/refstepcounter
, does not setcref@currentlabel
and thus breaks, e.g., thecleveref
package.
Inspired by your own answer/your hack I just came up with a variant where you get rid of the closing parenthese and which makes cref
possible also and which also works out when using the hyperref package.
Of course my variant does not resolve the tasks package's behavior of redefining @currentlabel
globally but does the same thing for cleveref's cref@currentlabel
.
The gist is:
I added another key "ugly-label-hook" to the tasks-package which lets you specify some tokens that get inserted whenever the tasks-package for one of its items modifies @currentlabel
.
You can use this hook for "refstepping" the "dummy"-counter for your subquestions/subanswers.
"refstepping" the "dummy"-counter makes sure the macros @currentlabel
and cref@currentlabel
are (re)defined correctly.
As the tasks-package does for whatever reason redefine @currentlabel
globally, with the "ugly-label-hook" it must be ensured that both @currentlabel
and cref@currentlabel
are (re)defined globally also.
documentclass[11pt]{article}
usepackage{hyperref}
usepackage{tasks,cleveref,xsim}
% ====Begin of patch of tasks.sty====
makeatletter
ExplSyntaxOn
% Allocate another token list for the ugly hack:
tl_new:N l__sillyugly_label_hook_tl
% Add a key "ugly-label-hook" for setting that
% token list:
keys_define:nn {tasks/list}
{
ugly-label-hook .tl_set:N = l__sillyugly_label_hook_tl ,
}
% Include the ugly-label-hook-key into the `tasks' object:
% #1: number of items
% #2: number of columns
% #3: label-format
DeclareObjectType {tasks} {3}
% the `default' template interface:
DeclareTemplateInterface {tasks} {default} {3}
{
enumerate : boolean = true ,
label : tokenlist ,
indent : length = 2.5em ,
counter-format : tokenlist = tsk[a]) ,
label-format : tokenlist ,
%----------------------------------------------------
ugly-label-hook : tokenlist ,
%----------------------------------------------------
label-width : length = 1em ,
label-offset : length = .3333em ,
item-format : tokenlist ,
after-item-skip : skip = 1ex plus 1ex minus 1ex
}
% When patching the next macro, the really unlikely marker $ with
% unusual catcode is used in ``$tasks$default$label$'':
cs_set:Nx __tasks_restore_dollar:
{ char_set_catcode:nn {36} { char_value_catcode:n {36} } }
char_set_catcode_alignment:N $
% Include the ugly-label-hook-key into the `default' template code
% and apply the hook when @currentlabel is changed:
DeclareTemplateCode {tasks} {default} {3}
{
enumerate = l__tasks_enumerate_bool ,
label = l__tasks_label_tl ,
indent = l__tasks_item_default_indent_dim ,
counter-format = l__tasks_label_pattern_tl ,
label-format = l__tasks_label_format_tl ,
%----------------------------------------------------
ugly-label-hook = l__sillyugly_label_hook_tl ,
%----------------------------------------------------
label-width = l__tasks_label_default_width_dim ,
label-offset = l__tasks_label_default_offset_dim ,
item-format = l__tasks_item_format_tl ,
after-item-skip = l__tasks_after_item_skip
}
{
AssignTemplateKeys
bool_if:NF l__tasks_label_width_bool
{
dim_set_eq:NN
l__tasks_label_width_dim
l__tasks_label_default_width_dim
}
bool_if:NF l__tasks_item_indent_bool
{
dim_set_eq:NN
l__tasks_item_indent_dim
l__tasks_item_default_indent_dim
}
bool_if:NF l__tasks_label_offset_bool
{
dim_set_eq:NN
l__tasks_label_offset_dim
l__tasks_label_default_offset_dim
}
% dim_compare:nNnT
% { l__tasks_item_indent_dim }
% <
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% {
% dim_set:Nn l__tasks_item_indent_dim
% { l__tasks_label_offset_dim + l__tasks_label_width_dim }
% }
bool_if:NT l__tasks_custom_after_item_skip_bool
{
skip_set_eq:NN
l__tasks_after_item_skip
l__tasks_custom_after_item_skip
}
bool_if:NT l__tasks_custom_label_bool
{
tl_set_eq:NN
l__tasks_label_tl
l__tasks_custom_label_tl
bool_set_false:N l__tasks_enumerate_bool
}
__tasks_label_align:V l__tasks_label_align_tl
% need this for enumerate list:
bool_if:nT { !l__tasks_resume_bool && l__tasks_enumerate_bool }
{ int_gzero:N g__tasks_int }
int_set:Nn l__tasks_columns_int {#2}
% set all the items in their own coffins and join with the ground:
int_gzero:N g__tasks_current_col_num_int
int_set:Nn g__tasks_current_row_num_int {1}
tl_if_blank:VF l__tasks_custom_label_pattern_tl
{
tl_set_eq:NN
l__tasks_label_pattern_tl
l__tasks_custom_label_pattern_tl
}
tl_if_blank:VF l__tasks_custom_label_format_tl
{
tl_set_eq:NN
l__tasks_label_format_tl
l__tasks_custom_label_format_tl
}
tl_if_blank:VF l__tasks_custom_item_format_tl
{
tl_set_eq:NN
l__tasks_item_format_tl
l__tasks_custom_item_format_tl
}
seq_map_inline:Nn l__tasks_seq
{
__tasks_read_item:www ##1 q_stop
bool_if:NTF l__tasks_enumerate_bool
{
tl_if_eq:VnT l__tasks_tmp_label_tl { $tasks$default$label$ }
{
int_gincr:N g__tasks_int
SaveCounterPatternFrom [tasks]
l__tasks_tmpa_tl
l__tasks_label_tl
l__tasks_label_pattern_tl
%-----------------------------------------------------------
% This seems to set @currentlabel globally:
%-----------------------------------------------------------
cs_gset:Npx @currentlabel { l__tasks_label_tl }
%-----------------------------------------------------------
% Carry out the ugly hook hack after setting @currentlabel
% for setting @currentlabel correctly.
% Seems with this package this needs to be done globally,
% thus uglycounterhack does it globally as well.
%-----------------------------------------------------------
l__sillyugly_label_hook_tl
}
}
{
tl_if_blank:VT l__tasks_label_tl
{ tl_set_eq:NN l__tasks_label_tl labelitemi }
}
tl_put_left:NV l__tasks_label_tl l__tasks_label_format_tl
% tl_put_left:NV l__tasks_item_tl l__tasks_item_format_tl
tl_if_eq:VnTF l__tasks_tmp_label_tl { $tasks$default$label$ }
{
__tasks_task:VVV
l__tasks_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
}
{
__tasks_task:VVV
l__tasks_tmp_label_tl
l__tasks_item_format_tl
l__tasks_item_tl
tl_clear:N l__tasks_tmp_label_tl
}
}
}
__tasks_restore_dollar:
ExplSyntaxOff
makeatother
% ====End of patch of tasks.sty====
DeclareExerciseTranslations{answer}{
Fallback = answer ,
English = answer ,
French = r'eponse ,
German = Antwort
}
DeclareExerciseType{question}{
exercise-env = question ,
solution-env = answer ,
exercise-name = XSIMtranslate{question} ,
solution-name = XSIMtranslate{answer} ,
exercise-template = default ,
solution-template = default
}
newcounter{subquestion}[question]
newcounter{subanswer}[answer]
renewcommand*thesubquestion{thequestion.arabic{subquestion}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubquestion{theHquestion.arabic{subquestion}}%
}%
renewcommand*thesubanswer{theanswer.arabic{subanswer}}%
csname @ifpackageloadedendcsname{hyperref}{%
renewcommand*theHsubanswer{theHanswer.arabic{subanswer}}%
}%
% cleveref-aliases/counter-naming-phrases:
crefname{question}{question}{questions}
crefname{subquestion}{subquestion}{subquestions} % has no effect, obviously
crefname{answer}{answer}{answers}
crefname{subanswer}{subanswer}{subanswers} % has no effect, obviously
makeatletter
% Why does the tasks-package its own counter-thingie when
% you have to use a counter anyway for getting things
% with label..ref done correctly? This does not make sense to me.
DeclareRobustCommanduglycounterhack[1]{%
refstepcounter{#1}%
globallet@currentlabel=@currentlabel
globalletcref@currentlabel=cref@currentlabel
}%
makeatother
NewTasks[%
%% This will not include the value of the question-counter
%% into the subquestion-items:
%% counter-format = tsk[1]),%
%% This will include the value of the question-counter
%% into the subquestion-items -- I recommend doing this for making
%% references to subquestion-items unambiguous:
counter-format = thequestion.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subquestion},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subquestionblock}[subquestion](2)
NewTasks[%
%% This will not include the value of the answer-counter
%% into the subanswer-items:
%% counter-format = tsk[1]),%
%% This will include the value of the answer-counter
%% into the subanswer-items -- I recommend doing this for making
%% references to subanswer-items unambiguous:
counter-format = theanswer.tsk[1]),%
label-format = itshape,%
ugly-label-hook = uglycounterhack{subanswer},%
label-width = 1.75em,%
item-indent = 2.55em,%
label-offset=0.8em,%
label-align=left,%
before-skip = 0pt,%
after-item-skip=0pt%
]{subanswerblock}[subanswer](2)
begin{document}
begin{question}[points=3]
Isomers of a coordination compound. label{iso}
begin{subquestionblock}
subquestion! Why do we have isomers? label{why}
subquestion! Why did I even ask cref{iso}? label{metawhy}
subquestion! What do you mean cref{metawhy}?
end{subquestionblock}
end{question}
begin{answer}[print=true]
begin{subanswerblock}
subanswer! Because isomers are fun. label{because}
subanswer! Because I am funny. label{metabecause}
subanswer! cref{metabecause} is funny but all in all this is no longer funny.
end{subanswerblock}
end{answer}
begin{question}[points=3]
Is there an end to stupid questions? label{stu}
begin{subquestionblock}
subquestion! Discuss why cref{metawhy} is a stupid question but cref{why} is even stupider? label{huh}
subquestion! Are both cref{huh} and cref{metawhy} both stupider that each other?
end{subquestionblock}
end{question}
end{document}
edited Sep 9 at 10:05
answered Sep 2 at 10:26
Ulrich Diez
4,085615
4,085615
hmmm ... this was lot more complicated than I thought. I really liked the packagestasks
andcleveref
. Thanks for all the effort that you put into helping me out @Ulrich .. I have also written a mail to the package authors.
– magguu
Sep 2 at 12:49
add a comment |
hmmm ... this was lot more complicated than I thought. I really liked the packagestasks
andcleveref
. Thanks for all the effort that you put into helping me out @Ulrich .. I have also written a mail to the package authors.
– magguu
Sep 2 at 12:49
hmmm ... this was lot more complicated than I thought. I really liked the packages
tasks
and cleveref
. Thanks for all the effort that you put into helping me out @Ulrich .. I have also written a mail to the package authors.– magguu
Sep 2 at 12:49
hmmm ... this was lot more complicated than I thought. I really liked the packages
tasks
and cleveref
. Thanks for all the effort that you put into helping me out @Ulrich .. I have also written a mail to the package authors.– magguu
Sep 2 at 12:49
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f448667%2fcustom-label-for-references-using-tasks-inside-a-xsim-exercise%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