getting ConTeXt results back to Lua (for typesetting solutions at end of document)
Dear List, I'm trying to have problem solutions automatically collected, each with its corresponding problem number, e.g. 2.3, and then typeset at the end of a document. Thus, I imagine something like \startproblem{A problem title} % Problem 1.1 A question \startsolution An answer \stopsolution \stopproblem And then the solution(s) would appear at the end (with the "1.1" remembered from when the problem was typeset): Solution to Problem 1.1. An answer It seems that buffers are the way to do this. But I cannot quite get the automatic numbering to work. The delayed evaluation and information passing between lua and ConTeXt has me confused and tangled in a knot. Below is a minimal almost-working example. The issue is in the line {\ctxlua{userdata.addTempToBuffer('#1', [==[\getnumber[problem]]==])}} which ends up putting the verbatim string "\getnumber[problem]" into the temp buffer, rather than the typeset result, which would be something like 1.1 or 1.2. I've read the cld-mkiv.pdf manual, but I must be missing a simple solution to getting ConTeXt to send back the result of \getnumber[problem]. I've also tried the analogous context.getnumber({"problem"}), though without success. Does anyone see what I am missing? Many thanks! -Sanjoy \defineenumeration[problem] [title=yes, text=Problem, way=bychapter, prefix=chapter] \defineenumeration[solution][problem] \setupenumeration [solution][text={Solution to problem}, number=no] \def\test#1{[#1]} % appendbuffer modified from Sietse Brouwer's on mailing list (Jan 15, 2013) \startluacode userdata = userdata or { } function userdata.addTempToBuffer(buffername, problem) buffers.append( buffername, '\\startsolution{' .. problem .. '}\n' .. buffers.getcontent('APPENDTEMP') .. '\n\\stopsolution\n\n' ) end \stopluacode \def\startappendbuffer[#1]% {\def\stopappendbuffer% {\ctxlua{userdata.addTempToBuffer('#1', [==[\getnumber[problem]]==])}} \dostartbuffer[APPENDTEMP][startappendbuffer][stopappendbuffer]} \starttext \chapter{One} \startproblem{Test} Test problem \startappendbuffer[soln] Solution \stopappendbuffer \stopproblem \startproblem{Test} Test problem \startappendbuffer[soln] Solution \stopappendbuffer \stopproblem \typebuffer[soln] \stoptext
Hi Sanjoy, when you have a equal number of questions ans answers you can create a enumeration for each and collect the answers with the block mechanism. At the end of the document you can flush the collected answers. \defineblock [answer] \defineenumeration [question] \defineenumeration [answer] \starttext \startquestion Question 1 \stopquestion \beginanswer \startanswer Answer 1 \stopanswer \endanswer \startquestion Question 2 \stopquestion \beginanswer \startanswer Answer 2 \stopanswer \endanswer \page \useblocks[answer] \stoptext Wolfgang Sanjoy Mahajan schrieb am 31.01.19 um 22:51:
Dear List,
I'm trying to have problem solutions automatically collected, each with its corresponding problem number, e.g. 2.3, and then typeset at the end of a document. Thus, I imagine something like
\startproblem{A problem title} % Problem 1.1 A question
\startsolution An answer \stopsolution
\stopproblem
And then the solution(s) would appear at the end (with the "1.1" remembered from when the problem was typeset):
Solution to Problem 1.1.
An answer
It seems that buffers are the way to do this. But I cannot quite get the automatic numbering to work. The delayed evaluation and information passing between lua and ConTeXt has me confused and tangled in a knot.
Below is a minimal almost-working example. The issue is in the line
{\ctxlua{userdata.addTempToBuffer('#1', [==[\getnumber[problem]]==])}}
which ends up putting the verbatim string "\getnumber[problem]" into the temp buffer, rather than the typeset result, which would be something like 1.1 or 1.2.
I've read the cld-mkiv.pdf manual, but I must be missing a simple solution to getting ConTeXt to send back the result of \getnumber[problem]. I've also tried the analogous context.getnumber({"problem"}), though without success.
Does anyone see what I am missing?
Many thanks!
-Sanjoy
\defineenumeration[problem] [title=yes, text=Problem, way=bychapter, prefix=chapter] \defineenumeration[solution][problem] \setupenumeration [solution][text={Solution to problem}, number=no]
\def\test#1{[#1]}
% appendbuffer modified from Sietse Brouwer's on mailing list (Jan 15, 2013) \startluacode userdata = userdata or { } function userdata.addTempToBuffer(buffername, problem) buffers.append( buffername, '\\startsolution{' .. problem .. '}\n' .. buffers.getcontent('APPENDTEMP') .. '\n\\stopsolution\n\n' ) end \stopluacode
\def\startappendbuffer[#1]% {\def\stopappendbuffer% {\ctxlua{userdata.addTempToBuffer('#1', [==[\getnumber[problem]]==])}} \dostartbuffer[APPENDTEMP][startappendbuffer][stopappendbuffer]}
\starttext
\chapter{One}
\startproblem{Test} Test problem \startappendbuffer[soln] Solution \stopappendbuffer \stopproblem
\startproblem{Test} Test problem \startappendbuffer[soln] Solution \stopappendbuffer \stopproblem
\typebuffer[soln]
\stoptext ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
A while back I asked a similar question, and Hans pointed out the following which I still use: \defineenumeration [exercise] [way=bysection, text=Exercise, coupling=solution, location=hanging] \defineenumeration [solution] [text=Solution, way=bysection, coupling=exercise, location=hanging] \defineblock[exercise] \defineblock[solution] \hideblocks[solution] \setupinteraction [state=start] \starttext \section{Main Text} \subsection[subsec:1]{problem section 1} \startexercise Addition\index{addition} problem: $1+1=?$ \stopexercise \beginsolution[one] \startsolution Answer: 2. \stopsolution \endsolution \subsection[subsec:2]{problem section 2} \startexercise Multiplication problem: $1\times1=?$ \stopexercise \beginsolution[two] \startsolution Answer: 1. \stopsolution \endsolution \page %\reset[solution] \section{Answers to the Problems} \subsection{Answers to \in{section}[subsec:1]} \useblocks[solution][one] \subsection{Answers to \in{section}[subsec:2]} \useblocks[solution][two] \stoptext
On Jan 31, 2019, at 5:02 PM, Wolfgang Schuster
wrote: Hi Sanjoy,
when you have a equal number of questions ans answers you can create a enumeration for each and collect the answers with the block mechanism.
At the end of the document you can flush the collected answers.
\defineblock [answer]
\defineenumeration [question] \defineenumeration [answer]
\starttext
\startquestion Question 1 \stopquestion
\beginanswer \startanswer Answer 1 \stopanswer \endanswer
\startquestion Question 2 \stopquestion
\beginanswer \startanswer Answer 2 \stopanswer \endanswer
\page
\useblocks[answer]
\stoptext
Wolfgang
Sanjoy Mahajan schrieb am 31.01.19 um 22:51:
Dear List, I'm trying to have problem solutions automatically collected, each with its corresponding problem number, e.g. 2.3, and then typeset at the end of a document. Thus, I imagine something like \startproblem{A problem title} % Problem 1.1 A question \startsolution An answer \stopsolution \stopproblem And then the solution(s) would appear at the end (with the "1.1" remembered from when the problem was typeset): Solution to Problem 1.1. An answer It seems that buffers are the way to do this. But I cannot quite get the automatic numbering to work. The delayed evaluation and information passing between lua and ConTeXt has me confused and tangled in a knot. Below is a minimal almost-working example. The issue is in the line {\ctxlua{userdata.addTempToBuffer('#1', [==[\getnumber[problem]]==])}} which ends up putting the verbatim string "\getnumber[problem]" into the temp buffer, rather than the typeset result, which would be something like 1.1 or 1.2. I've read the cld-mkiv.pdf manual, but I must be missing a simple solution to getting ConTeXt to send back the result of \getnumber[problem]. I've also tried the analogous context.getnumber({"problem"}), though without success. Does anyone see what I am missing? Many thanks! -Sanjoy \defineenumeration[problem] [title=yes, text=Problem, way=bychapter, prefix=chapter] \defineenumeration[solution][problem] \setupenumeration [solution][text={Solution to problem}, number=no] \def\test#1{[#1]} % appendbuffer modified from Sietse Brouwer's on mailing list (Jan 15, 2013) \startluacode userdata = userdata or { } function userdata.addTempToBuffer(buffername, problem) buffers.append( buffername, '\\startsolution{' .. problem .. '}\n' .. buffers.getcontent('APPENDTEMP') .. '\n\\stopsolution\n\n' ) end \stopluacode \def\startappendbuffer[#1]% {\def\stopappendbuffer% {\ctxlua{userdata.addTempToBuffer('#1', [==[\getnumber[problem]]==])}} \dostartbuffer[APPENDTEMP][startappendbuffer][stopappendbuffer]} \starttext \chapter{One} \startproblem{Test} Test problem \startappendbuffer[soln] Solution \stopappendbuffer \stopproblem \startproblem{Test} Test problem \startappendbuffer[soln] Solution \stopappendbuffer \stopproblem \typebuffer[soln] \stoptext ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
Thank you, Matthias and Wolfgang, for the examples/solutions. If I understand them right, there must be one solution for each exercise (otherwise the solution numbering gets out of sync). Or do the coupling= options in Matthias's example remove that restriction? In my experiments with the examples, deleting the first solution unsynchronized the exercise--solution numbering, no matter how I fiddled with the coupling keys. In the ideal pedagogical world, I'd write a solution for each exercise. But reality might intervene, so I still wonder if the solutions can automatically know and include the exercise number (perhaps by placing \startanswer..\stopanswer inside \startexercise..\stopexercise and using \getnumber[exercise]). If there is a clever way, that's great. But, the nature of TeX as a macro language may preclude the \getnumber code being evaluated just when one wants. Regards, -Sanjoy
Hi,
this is what I learned from the list to use. I'm sorry, but the names
sound a bit Swedish, but I'm sure you can change that. This way it was
also easy to add different types like hints, answers and solutions and
get clickable letters accordingly.
/Mikael
%Test file
\setupinteraction[state=start,color=,contrastcolor=,style=]
\define[1]\problemtextmakro
{%
\doifreferencefoundelse{losn:\currentconstructionreference}
{\llap{\goto{{\WORD l}}[losn:\currentconstructionreference]}\,}
{}%
#1
}
\defineenumeration[problem][
referenceprefix=problem,
text=,
width=fit,
numbercommand=\problemtextmakro,
number=yes,
alternative=serried,
hang=margin,
indentnext=auto,
indenting={yes,small},
prefix=yes,
prefixsegments=chapter,
way=bychapter,
]
\defineblock[losn]
\hideblocks[losn]
\define[1]\losntextmakro
{\doifreferencefoundelse{problem:\currentconstructionreference}
{\bf \goto{\WORD{\in[problem:\currentconstructionreference]}}[problem:\currentconstructionreference]}
{}
}
\defineenumeration[losning][
referenceprefix=losn,
numbercommand=\losntextmakro,
text=,
headstyle=,
title=yes,
titlestyle=,
alternative=serried,
width=fit,
number=no,
indentnext=auto,
indenting={yes,medium},
before={\blank[halfline]},
after={\blank[halfline]},
]
\starttext
\chapter{Problems}
\startproblem[p:cont]
Show that all functions are continuous.
\stopproblem
\beginlosn
\startlosning[p:cont]
All functions are continuous\ldots
\stoplosning
\endlosn
\startproblem
This is a problem without solution
\stopproblem
\startproblem[p:diff]
Show that all functions are differentiable.
\stopproblem
\beginlosn
\startlosning[p:diff]
All functions are differentiable\ldots
\stoplosning
\endlosn
\beginlosn
\startlosning[p:diff]
This is a second solution to~\in[p:diff].\ldots
\stoplosning
\endlosn
\chapter{Solutions}
\selectblocks[losn][criterium=all]
On Fri, Feb 1, 2019 at 5:20 AM Alan Braslau
On Thu, 31 Jan 2019 22:10:40 -0500 Sanjoy Mahajan
wrote: Thank you, Matthias and Wolfgang, for the examples/solutions.
Why not use the list mechanism?
Alan ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
On 2019-02-01 07:58, "Mikael P. Sundqvist"
this is what I learned from the list to use. I'm sorry, but the names sound a bit Swedish, but I'm sure you can change that.
The Swedish is not a problem. Swedish, like Dutch, seems to be (English + German)/2. Or sqrt(English*German) if, like me, you prefer the geometric mean.
This way it was also easy to add different types like hints, answers and solutions and get clickable letters accordingly.
Thank you. I'll incorporate pieces into my setups. If it ends up an improvement over what's on the wiki, I'll also wikify. -Sanjoy
What you probably mean is that Swedish, German, Dutch and English are Indo-European Germanic languages which have much in common. This cannot be expressed in terms of blends, products or square roots from one another. What they do have is a common root, like \sqrt(indo-european) $x$ w = Swedish, \sqrt(indo-european) $x$ x = Dutch, \sqrt(indo-european) $x$ y = German, \sqrt(indo-european) $x$ z + Latin + French = English, etc. And yes, Sanskrit, Farsi, Kurdish, Urdu and Hindi are indo-European languages too, each in their own right. Robert
Op 1 feb. 2019, om 17:16 heeft Sanjoy Mahajan
het volgende geschreven: On 2019-02-01 07:58, "Mikael P. Sundqvist"
wrote: this is what I learned from the list to use. I'm sorry, but the names sound a bit Swedish, but I'm sure you can change that.
The Swedish is not a problem. Swedish, like Dutch, seems to be (English + German)/2. Or sqrt(English*German) if, like me, you prefer the geometric mean.
This way it was also easy to add different types like hints, answers and solutions and get clickable letters accordingly.
Thank you. I'll incorporate pieces into my setups. If it ends up an improvement over what's on the wiki, I'll also wikify.
-Sanjoy ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
Hi Sanjoy, Two or three years ago Wolfgang helped me to solve an analogous question. Here is an example which works fine, and moreover one can navigate from a question to its hint (if there is one…) and then from the hint to its solution (if present…). Best regards: OK %%%% begin interactive-question-hint-answer.tex %%%% Here, following Wolfgang Schuster's ideas, %%%% we define some macros allowing to couple %%%% Questions, Hints and Answers in an automatic way %%%% Upon clicking on an interactive title for Question, Hint or Answer %%%% one goes to the corresponding Hint, Answer or Question \setupinteraction[state=start] % We define two counters which follow the numbers % appearing in Question and Answer \newcounter\QuestionCounter \newcounter\HintCounter \newcounter\AnswerCounter % We create two commands to be used in the % enumeration environments % Note that the check for trial typestting % \doifnotmode{*trialtypesetting} % is necessary in order to avoid unwanted incrementation \define[1]\QuestionTextCommand {\doifnotmode{*trialtypesetting} {\doglobal\increment\QuestionCounter \pagereference[question:\QuestionCounter]}% \doifreferencefoundelse{hint:\QuestionCounter} {\goto{#1}[hint:\QuestionCounter]} {#1}} \define[1]\HintTextCommand {\doifnotmode{*trialtypesetting} {\doglobal\increment\HintCounter \pagereference[hint:\HintCounter]}% \doifreferencefoundelse{answer:\QuestionCounter} {\goto{#1}[answer:\QuestionCounter]} {#1}} \define[1]\AnswerTextCommand {\doifnotmode{*trialtypesetting} {\doglobal\increment\AnswerCounter \pagereference[answer:\AnswerCounter]}% \doifreferencefoundelse{question:\AnswerCounter} {\goto{#1}[question:\AnswerCounter]} {#1}} % We define here two enumeration environments for % Questions and Answers \defineenumeration[question] [text=Question, headcommand=\QuestionTextCommand, number=yes, prefix=yes, prefixsegments=chapter, coupling=hint] \defineenumeration[hint] [text=Hint, headcommand=\HintTextCommand, number=yes, prefix=yes, prefixsegments=chapter, coupling=answer] \defineenumeration[answer] [text=Answer, headcommand=\AnswerTextCommand, number=yes, prefix=yes, prefixsegments=chapter, coupling=question] % Each question is followed immediately by its answer. % The answers are put in a block which will be used later \defineblock[hint] \hideblocks[hint] \defineblock[answer] \hideblocks[answer] % We define a command used after a % Question for which no Answer is provided % Since the block commands % \beginanswer ... \endanswer % cannot be used directly in a macro definition % we use a trick... % In the buffer the two counters associated to Answer % are incremented... \startbuffer[noanswer] \beginhint \doglobal\increment\HintCounter \incrementcounter[hint] \endhint \beginanswer \doglobal\increment\AnswerCounter \incrementcounter[answer] \endanswer \stopbuffer % ...and then the above buffer is invoked \define\noanswer {\getbuffer[noanswer]} % example of use: \starttext \startchapter[title=Questions] \startquestion[q:1] Prove that ${\rm e}\sim 2.73$ is irrational. This is the first question, with its own reference, for later use. \stopquestion \beginhint \starthint Write ${\rm e}$ as a series. \stophint \endhint \beginanswer \startanswer This is the answer to the first question (to \in{Question}[q:1]). \stopanswer \endanswer \startquestion This is the second question, without its own reference. \stopquestion \beginhint \starthint Do you really need a hint? :-) \stophint \endhint \beginanswer \startanswer[a:Test] This is the answer to the second question. (Note that this answer has a reference named \type{a:Test}). \stopanswer \endanswer \startquestion[q:Obvious] This is the third question, an easy one, without a given solution. \stopquestion % we increment here the counters for Answer \noanswer \startquestion[q:2] This is the fourth question with its own reference. \stopquestion \beginhint \starthint Do you really need a hint? :-) \stophint \endhint \beginanswer \startanswer This is the answer to the fourth question: use the result of \in{Question}[q:1]. \stopanswer \endanswer \startquestion This is the fifth question, without its own reference. ({\it Hint:} look again at \in{Question}[q:Obvious]). \stopquestion \beginhint \starthint Do you really need a hint? :-) \stophint \endhint \beginanswer \startanswer This is the answer to the fifth question. Read again \in{Answer}[a:Test]. \stopanswer \endanswer \stopchapter % Here we say ownnumber=1, in order to match the prefix % of numbers associated to Answer \startchapter[ownnumber=1,title=Hints] \useblocks[hint] \stopchapter \startchapter[ownnumber=1,title=Answers and solutions] \useblocks[answer] \stopchapter \stoptext %%%% end interactive-question-hint-answer.tex
On 1 Feb 2019, at 04:10, Sanjoy Mahajan
wrote: Thank you, Matthias and Wolfgang, for the examples/solutions.
If I understand them right, there must be one solution for each exercise (otherwise the solution numbering gets out of sync). Or do the coupling= options in Matthias's example remove that restriction? In my experiments with the examples, deleting the first solution unsynchronized the exercise--solution numbering, no matter how I fiddled with the coupling keys.
In the ideal pedagogical world, I'd write a solution for each exercise. But reality might intervene, so I still wonder if the solutions can automatically know and include the exercise number (perhaps by placing \startanswer..\stopanswer inside \startexercise..\stopexercise and using \getnumber[exercise]). If there is a clever way, that's great. But, the nature of TeX as a macro language may preclude the \getnumber code being evaluated just when one wants.
Regards, -Sanjoy ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
On 2/1/2019 4:10 AM, Sanjoy Mahajan wrote:
Thank you, Matthias and Wolfgang, for the examples/solutions.
If I understand them right, there must be one solution for each exercise (otherwise the solution numbering gets out of sync). Or do the coupling= options in Matthias's example remove that restriction? In my experiments with the examples, deleting the first solution unsynchronized the exercise--solution numbering, no matter how I fiddled with the coupling keys.
In the ideal pedagogical world, I'd write a solution for each exercise. But reality might intervene, so I still wonder if the solutions can automatically know and include the exercise number (perhaps by placing \startanswer..\stopanswer inside \startexercise..\stopexercise and using \getnumber[exercise]). If there is a clever way, that's great. But, the nature of TeX as a macro language may preclude the \getnumber code being evaluated just when one wants. given that context originally was made for typesetting educational materials including questions, answers, explanations ... how about looking at the 'blocks' mechanism (there are some examples in the test suite under blocks)
Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
On 2019-02-01 09:48, Hans Hagen
given that context originally was made for typesetting educational materials including questions, answers, explanations ... how about looking at the 'blocks' mechanism (there are some examples in the test suite under blocks)
They are very helpful; thank you. Those and Mikail's example are also inspiring me to provide a hint and a solution for each problem, not just a solution. By the way, in the test suite (from the PRAGMA site), blocks-001.tex crashes the 2019.01.28 beta here on my Debian amd64 system, with the following error on the terminal (no log file is even produced): $ mycontext blocks-001.tex /home/sanjoy/context/2019.01.28-beta/tex/texmf-linux-64/bin/context /home/sanjoy/context/2019.01.28-beta/tex/texmf-linux-64/bin/luatex ...ta/tex/texmf-context/scripts/context/lua/mtx-context.lua:427: attempt to call a nil value (global 'restart') (The two file paths that are printed first are for my own debugging, to ensure that the run is using the context and luatex binaries from the minimals installation.) The culprit seems to be the "% engine=luatex" first line. At least, deleting it fixes the problem. Meanwhile, blocks-003.tex doesn't have it, and it runs fine. About the test-suite wiki page...actually, I'll start a new thread for that topic as it's not directly related to problems/solutions/blocks. -Sanjoy
participants (8)
-
Alan Braslau
-
Hans Hagen
-
Mikael P. Sundqvist
-
Otared Kavian
-
r.ermers@hccnet.nl
-
Sanjoy Mahajan
-
Weber, Matthias
-
Wolfgang Schuster