PROGRESS!! I've actually got a baby version of this working. I'm eager for advice about how best to polish this and integrate it in a way that isn't as hacky as this current first attempt is. Here's what I did.
1. The easy part: In a test document, I run a sagesilent to define a Problem class, which has just two methods, a constructor that takes a pile of text and builds a problem from it, and instance(), which creates an instance of the problem and returns it as a string. The text that the constructor expects is three or more TeX paragraphs: The first is the problem name, the next is a bunch of sage code that initializes the problem (and will be run for each separate instance), and the rest are the problem text, including $\sage{...}$ references to variables created in the initialization section. It looks like this. (It could have many features added later; this is version 0.01.) \begin{sagesilent} from string import * class Problem: allProblems = {} def __init__ ( self, text ): text = replace( text.strip(), '\n ', '\n' ) text = text.split( '\n\n' ) self._name = text.pop( 0 ) if len( text ) > 0 else 'Unnamed' self._setup = text.pop( 0 ) if len( text ) > 0 else '' self._text = '\\\\'.join( text ) Problem.allProblems[self._name] = self def instance ( self ): vars = {} sage_eval( 'None', cmds=self._setup, locals=vars ) copy = self._text while copy.find( '\\sage{' ) > -1: start = copy.find( '\\sage{' ) stop = copy.find( '}', start ) inside = copy[start+6:stop] copy = copy[:start] + str( sage_eval( inside, locals=vars ) ) + copy[stop+1:] return copy \end{sagesilent} 2. The tricky part: I modified sagetex.sty itself, adding these lines immediately after the definition of sagesilent. They are a nearly-identical copy of the definition of sagesilent, with two changes. First, this environment (sageprocesstext) takes a parameter, which should be the name of a Sage function. Second, it quotes its entire contents and passes them as a big string parameter to said function. Hence the name sageprocesstext, because it takes the entire TeX-like text inside the environment and pass it to the sage function, evaluating the result silently, like a sagesilent environment would. \newenvironment{sageprocesstext}[1]{\ST@beginsfbl% \ST@wsf{ #1(r"""}% \def\verbatim@processline{\ST@wsf{ \the\verbatim@line}}% \verbatim@start}% {\ST@wsf{""")}\ST@endsfbl\@esphack} 3. The fun part: I define problems thereafter in my document like this: \begin{sageprocesstext}{Problem} First Problem a = randint(1,20) b = randint(1,20) The true facts of addition include $\sage{a}+\sage{b}=\sage{a+b}$. \end{sageprocesstext} and put instances of my problems into my document using this new command, defined at the top of the test file: \newcommand\insertproblem[1]{\sagestr{Problem.allProblems["#1"].instance()}} like so: \insertproblem{First Problem} \insertproblem{First Problem} And it works! I get a document with this in it: The true facts of addition include 18 + 20 = 38. The true facts of addition include 15 + 3 = 18. Woohoo! Obviously this could be extended to support problem solutions as well, with a little work. The intent is that the text in green above is the only stuff that the average user would have to type, and the rest of it could be moved off into a .sty file that they include. So, here's some types of advice I'd love to receive on this: 1. Should I actually be suggesting changes to sagetex.sty? Or is there a way to do that in my own .sty file? I couldn't call Dan's ST@stuff commands from my own document, because I think TeX @ things are local or something...*mumbles cluelessly* 2. Not sure if I can run sagesilent blocks when not inside a document, which I'd need to do to move the class definition into a .sty file. Or should I use something like \AtBeginDocument? Not sure if that will work either. TeX is so touchy, and I'm rather new at this. 3. The goal is, of course, to get this nicely packaged into a single .sty file that includes sagetex.sty, and then add the features mentioned above, and then contribute it...someplace. When the time comes, what's the appropriate "someplace"? Thanks! Nathan On Friday, March 1, 2013 2:19:56 PM UTC-5, Nathan Carter wrote: > > > Yeah, you're right, but I'm still going to argue. :) > > Indeed, the whole thing would work in Sage exclusively, or a combination > of Sage and TeX (beyond SageTeX). Here are the priorities I was operating > under; all are priorities for the end user of the package, not for the > author of the package. (If I prioritized the needs of the author, I would > simply abandon the project and play Wii with my kids instead. That's > maximal convenience right there!) > > 1. If possible, do everything in one file rather than more than one, > and one piece of software, rather than more than one. Putting everything > in one LaTeX file (with optional problem bank .sty files for those who > need > that) or one Sage notebook (again, with optional problem banks) would > satisfy this constraint. > 2. If possible, let the user operate in TeX rather than Sage, for > several reasons. > 1. Most of what they write will be TeX, and only a little will be > Sage. > 2. Most people are more comfortable in TeX than Sage. > 3. The user retains the freedom to put all manner of comments, > images, headings, etc. before/between problems, etc. > 4. Doing it in Sage means putting potentially nontrivial amounts of > code in quotes (or user-defined functions or lambdas), which is > awkward, > and unnerving to Python/Sage newbies. Doing it in TeX (I had hoped) > could > make this step invisible to the user. > > I don't mean to ignore your wisdom that it's easier and more reliable to > build stuff in Sage than in TeX; I not only confess that you know both > better than I do, but even what I have seen of both makes me agree with > you. I'm just saying that I was shooting to build the thing that would be > maximally easy to use when I was done, and I don't think that something > built in Sage is that thing, even before I consider the additional step of > running it through TeX as a second step. > > In fact, it would be sufficiently less easy to use that I don't think I'd > invest the effort in building it in the first place; my expected > satisfaction with the end result isn't enough to motivate it. > > So my last attempt to get this to work will be along these lines: > > 1. If you don't mind, Dan, can you give me a little bit more > information about exactly how it is that the verbatim-like nature of > sagesilent blocks don't play well with \def and \newcomand? Here's why: > 2. I'll take that information over to TeX stack exchange (where some > people know astonishing amounts about the guts of LaTeX, btw) and see if > any of them can tell me a workaround for how to get sagesilent > environments > to work inside \def or \newcommand. > > If that works, I'll use it and do my original plan. And if it doesn't, > I'm giving up with a clean conscience. :) > > N > > > On Friday, March 1, 2013 12:24:36 PM UTC-5, Dan Drake wrote: >> >> On Thu, 28 Feb 2013 at 06:46PM -0800, Nathan Carter wrote: >> > Sure. The goal is to create a LaTeX package for randomly generated >> exams. >> > It should let you do something like this: >> >> [snip] >> >> You know, it looks like what you _really_ want is a WebWorK server. :) >> >> Looking briefly over your TeX stuff, my first thought is that you could >> write a Sage/Python program that generated the problems, wrote them into >> a file that TeX could read (a variation on the .sagetex.sout file), and >> then in your exam file, just read them in. >> >> That works on a principle that I've learned working with SageTeX: do as >> much as you can in Sage/Python, because programming there is sane and >> reasonable, unlike programming in TeX. >> >> Dan >> >> -- >> --- Dan Drake >> ----- http://math.pugetsound.edu/~ddrake >> ------- >> > -- You received this message because you are subscribed to the Google Groups "sage-edu" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-edu+unsubscr...@googlegroups.com. To post to this group, send email to sage-edu@googlegroups.com. Visit this group at http://groups.google.com/group/sage-edu?hl=en. For more options, visit https://groups.google.com/groups/opt_out.