Closed Alex-Jordan closed 3 months ago
MathView renders whatever students put in the answer box using MathJax. Unfortunately there isn't a lot of information available on the js side for MathJax to determine what strings are special for a given problem or what they should translate to. Basically, given that all different answers are typed into a text box, it is difficult to tell if a given sequence of characters should be rendered as mathematics or as text. Some options I can think of would be
I think the problem is actually that MathView uses MathJax's AsciiMath format to parse the student answer, and although AsciiMath is similar to WeBWorK's algebra notation, it is not identical. In particular, AsciiMath includes many more symbols than WeBWorK does. For example, AsciiMath has all the Greek letters (via alpha
and beta
, etc), and prod
, sum
and int
, and RR
for the set of reals, and -<
for TeX's \prec
, and in
for \in
, and oo
for infinity, and a whole lot of others. So AsciiMath parses all kinds of things that WeBWorK doesn't. It also uses (:
and :)
for vectors rather than <
and >
(since those mean less-than and greater-than in AsciiMath). SO there are a number of significant differences between the two, and the AsciiMath results are only moderately equivalent to the MathObject results, in general.
A solution might be to have the MathJax configuration for MathView remove all the unwanted symbols from AsciiMath (and perhaps add "inf" and "infinity" for \infty, and perhaps set <
and >
as vector brackets). It would be rather extensive changes to the AsciiMath list, but it could be done.
I had not thought about removing the unwanted asciimath symbols, but that would also be necessary. I already change \ to a power and not a star, so the pathway for these changes are there.
One has exactly the same issues with "Show Past Answers" for the same reason. See the discussion at http://webwork.maa.org/moodle/mod/forum/discuss.php?d=3771 As far as "Show Past Answers" is concerned, I and others would much prefer to see exactly what the student entered, not a typeset version of their answer which, in the original case that let to the above post, was confusing for the instructor.
I agree with Arnie; I prefer to see what the student actually typed, not a typeset version.
Sorry. I just thought that having it easier to read would be worth it overall. I'll make a pull request to change it back.
Could it be a choice? Perhaps a toggle on the page that would switch between the views? I'm sure there are people who prefer the typeset version (or at times do).
The other possibility is an overlay. In responding to entries for the current problem I chose one version (usually typeset mode) and allowed you to get the direct input as a popup by hovering over the field. This wasn't enough for some people :-) but it allowed access to the alternative format.
One problem, and the one Gavin first reported, is that in some cases you can not tell the difference between typeset mode and direct input if you are not specifically testing for this (and most instructors would have no reason to). If you look at the forum post, Gavin did not figure out what was going on (he didn't look hard) and it took me quite a while and a wrong guess to become aware that MathJax was the "problem" which was confirmed by Davide. In Gavin's case, Past Answers showed the answers sin(.25x), sin e(.25x), sin(.25x), and sin(.25x) and only the last answer was marked correct by WeBWorK. As Gavin reported the actual answers the student submitted were Sin(.25x), Sine(.25x), Sin(.25x), and sin(.25x). An instructor less knowledgeable about WeBWorK than Gavin would probably conclude the student entered the correct answer (sin(.25x)) and WeBWorK marked it wrong and, for some strange reason, the last time the student entered the correct answer, it was accepted. As noted in one of my and David's forum posts, right now you can easily see the actual answer the student entered, but it's not an obvious thing for an instructor to do (Gavin didn't do it and neither did I until the very end). So, if we do have a typeset mode, I would definitely want the raw input mode to be the default.
Another comment is whether (especially for MathView) it is feasible to substitute the WeBWorK's parser for MathJax's AsciiMath parser?
MathJax runs in the browser, which means it is Javascript, but WeBWorK's parser is on the server in Perl. It would require a complete port of MathObjects to javascript to make that possible.
With MathJax v2.6 (currently in beta), it would be possible to use MathJax-node to process the math on the server to produce the HTML that MathJax would create in the browser. That could be cached just like the current image mode results. That doesn't help MathView, but it could be useful for past answers, as well as for problems in general.
The main issue with having a "switch" to turn typesetting on and off is that it doesn't really solve Arnie/Gavin's problem. If you suspect that its the actual answer text that is the issue you can already right click on the typeset formula to see the original answer. The issue is that unless you know or suspect that the raw answer is the problem you would never think to do that, and you wouldn't think to turn off typesetting either. Maybe building a typeset mode for mathjax which more closely mimics PG would solve the issue because it would fail on things like Sin(.25).
What I had in mind was more of a preference so that people could see the form they wanted, not something intended to solve Gavin's problem directly.
As for a MathJax input that is more like MathObjects, the difficulty is that what parses and what doesn't is dependent on the answer's Context object, and that varies considerably from one context to another. E.g., in the vector contexts, "<" and ">" are delimiters for vectors, but in the Inequalities context, these are less-than and greater-than. You can't tell which way "<" and ">" are to be treated without knowing the context, so in order to make that work, you would need to have a tighter connection between the page displaying the math and the problem from which the answers came. My main objection to typesetting the answer has always been that you don't have that connection, so will misrepresent answers that are not in the basic numeric contexts. Things like currency, or scientific notation, or permutations, or other special-purpose contexts may not render correctly without the specialized knowledge of the context that the problem has but the instructor page doesn't.
Returning to this after a long hiatus. @dpvc suggested that to address the MathView issue, we could remove all the unwanted symbols from AsciiMath and add a few WW-specific items back. I've looked around the MathJax and AsciiMath documentation, but I can't find how to remove things that the AsciiMath parser recognizes. Can you point me in the right direction?
I did find how to change things that the parser already recognizes, following Geoff's note above about **
. However, the lines in webwork2/htdocs/js/apps/MathView/mathview.js, that are intended to make it recognize **
and output ^
are broken. Typing **
still makes an asterisk for me. I removed the var
from line 24 of that file, and then typing **
makes a caret. I don't understand javascript well enough to explain this, but is this a bug/typo, and is removing var
the right fix?
I also believe I have found how to add new things, like make it recognize inf
and behave like oo
nomrally behaves. However I can't see how to make it be case insensitive. Will I need to add INF
, Inf
, etc. separately?
@Alex-Jordan, I think if you replace lines 23 to 32 by
MathJax.Hub.Register.StartupHook("AsciiMath Jax Config", function () {
var AM = MathJax.InputJax.AsciiMath.AM;
AM.symbols.splice(0,AM.symbols.length); // remove all definitions
AM.symbols.push.apply(AM.symbols,[
{input:"(", tag:"mo", output:"(", tex:"left(", ttype:AM.TOKEN.LEFTBRACKET},
{input:")", tag:"mo", output:")", tex:"right)", ttype:AM.TOKEN.RIGHTBRACKET},
{input:"[", tag:"mo", output:"[", tex:"left[", ttype:AM.TOKEN.LEFTBRACKET},
{input:"]", tag:"mo", output:"]", tex:"right]", ttype:AM.TOKEN.RIGHTBRACKET},
{input:"{", tag:"mo", output:"{", tex:null, ttype:AM.TOKEN.LEFTBRACKET},
{input:"}", tag:"mo", output:"}", tex:null, ttype:AM.TOKEN.RIGHTBRACKET},
{input:"|", tag:"mo", output:"|", tex:null, ttype:AM.TOKEN.LEFTRIGHT},
{input:"<", tag:"mo", output:"\u2329", tex:"langle", ttype:AM.TOKEN.LEFTBRACKET},
{input:">", tag:"mo", output:"\u232A", tex:"rangle", ttype:AM.TOKEN.RIGHTBRACKET},
{input:"inf", tag:"mo", output:"\u221E", tex:"infty", ttype:AM.TOKEN.CONST},
{input:"Inf", tag:"mo", output:"\u221E", tex:"infty", ttype:AM.TOKEN.CONST},
{input:"INF", tag:"mo", output:"\u221E", tex:"infty", ttype:AM.TOKEN.CONST},
{input:"infinity", tag:"mo", output:"\u221E", tex:"infty", ttype:AM.TOKEN.CONST},
{input:"Infinity", tag:"mo", output:"\u221E", tex:"infty", ttype:AM.TOKEN.CONST},
{input:"INFINITY", tag:"mo", output:"\u221E", tex:"infty", ttype:AM.TOKEN.CONST},
{input:"none", tag:"mtext", output:"NONE", tex:null, ttype:AM.TOKEN.CONST},
{input:"None", tag:"mtext", output:"NONE", tex:null, ttype:AM.TOKEN.CONST},
{input:"NONE", tag:"mtext", output:"NONE", tex:null, ttype:AM.TOKEN.CONST},
{input:"dne", tag:"mtext", output:"DNE", tex:null, ttype:AM.TOKEN.CONST},
{input:"Dne", tag:"mtext", output:"DNE", tex:null, ttype:AM.TOKEN.CONST},
{input:"DNE", tag:"mtext", output:"DNE", tex:null, ttype:AM.TOKEN.CONST},
{input:"sin", tag:"mi", output:"sin", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"cos", tag:"mi", output:"cos", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"tan", tag:"mi", output:"tan", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"cot", tag:"mi", output:"cot", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"sec", tag:"mi", output:"sec", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"csc", tag:"mi", output:"csc", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"asin", tag:"mi", output:"asin", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"acos", tag:"mi", output:"acos", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"atan", tag:"mi", output:"atan", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"acot", tag:"mi", output:"acot", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"asec", tag:"mi", output:"asec", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"acsc", tag:"mi", output:"acsc", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"asin", tag:"mi", output:"asin", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arccos", tag:"mi", output:"arccos", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arctan", tag:"mi", output:"arctan", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arccot", tag:"mi", output:"arccot", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arcsec", tag:"mi", output:"arcsec", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arccsc", tag:"mi", output:"arccsc", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"sinh", tag:"mi", output:"sinh", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"cosh", tag:"mi", output:"cosh", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"tanh", tag:"mi", output:"tanh", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"coth", tag:"mi", output:"coth", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"sech", tag:"mi", output:"sech", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"csch", tag:"mi", output:"csch", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"asinh", tag:"mi", output:"asinh", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"acosh", tag:"mi", output:"acosh", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"atanh", tag:"mi", output:"atanh", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"acoth", tag:"mi", output:"acoth", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"asech", tag:"mi", output:"asech", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"acsch", tag:"mi", output:"acsch", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"asinh", tag:"mi", output:"asinh", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arccosh", tag:"mi", output:"arccosh", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arctanh", tag:"mi", output:"arctanh", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arccoth", tag:"mi", output:"arccoth", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arcsech", tag:"mi", output:"arcsech", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arccsch", tag:"mi", output:"arccsch", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"exp", tag:"mi", output:"exp", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"int", tag:"mi", output:"int", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"sgn", tag:"mi", output:"sgn", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"atan2",tag:"mi", output:"sgn", tex:"atan_2", ttype:AM.TOKEN.UNARY, func:true},
{input:"abs", tag:"mi", output:"abs", tex:null, ttype:AM.TOKEN.UNARY, rewriteleftright:["|","|"]},
{input:"norm", tag:"mi", output:"norm", tex:null, ttype:AM.TOKEN.UNARY, rewriteleftright:["|","|"]},
{input:"unit", tag:"mi", output:"unit", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"arg", tag:"mi", output:"arg", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"mod", tag:"mi", output:"mod", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"Re", tag:"mi", output:"Re", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"Im", tag:"mi", output:"Im", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"cong", tag:"mover", output:"\u00AF", tex:"overline", ttype:AM.TOKEN.UNARY, acc:true},
{input:"log", tag:"mi", output:"log", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"log10",tag:"mi", output:"log10", tex:"log_{10}", ttype:AM.TOKEN.UNARY, func:true},
{input:"ln", tag:"mi", output:"ln", tex:null, ttype:AM.TOKEN.UNARY, func:true},
{input:"sqrt", tag:"msqrt",output:"sqrt", tex:null, ttype:AM.TOKEN.UNARY},
{input:"*", tag:"mo", output:"\u22C5", tex:"cdot", ttype:AM.TOKEN.CONST},
{input:"/", tag:"mfrac",output:"/", tex:null, ttype:AM.TOKEN.INFIX},
{input:"^", tag:"msup", output:"^", tex:null, ttype:AM.TOKEN.INFIX},
{input:"**", tag:"msup", output:"^", tex:null, ttype:AM.TOKEN.INFIX},
{input:"U", tag:"mo", output:"\u222A", tex:"cup", ttype:AM.TOKEN.CONST},
{input:"><", tag:"mo", output:"\u00D7", tex:"times", ttype:AM.TOKEN.CONST}
]);
});
Note that line 32 should be deleted, as it is both unnecessary and syntactically incorrect.
That should remove all the existing symbols in AsciiMath and replace them with the ones that correspond to the standard MathObjects "Full" context. It should cover the needs of all the default contexts, but won't properly handle ones like inequalities (since that defines additional operators for the relations <
, >
, and so on). It also won't include any new strings that get added to the context by the problem author.
Yes, you do need to do the various capitalizations, as AsciiMath doesn't have a case-insensitive mode. I've included inf
, Inf
, and INF
(and the other values like that).
See if that doesn't do more what you want.
Thanks Davide. I was going to go through that list in Default.pm myself once I had the basics, but you spared me that. I added pi
and a few other things like inequality symbols, even though they won't be recognized by WW for many answers. (And I commented out the vector brackets.)
I thought I had this all working, but then at the end it appears to work with Chrome, but not Firefox or Safari. Chrome is honoring the MathJax configuration for MathView separately from the configuration for the rest of the WW page. But with both Safari and Firefox, MathView's use of MathJax appears to use the ambient MathJax configuration instead of this specially built one.
You can try this live problem in the different browsers and see. In Safari, the draggability is broken, so instead of using the menus, just open MathView and type infinity
. With Chrome I see the infinity symbol, but with the others I see \in f\in ity
. Assuming you see the same, can anything be done to get it to honor the right configuration?
@Alex, I expect the issue is that the configuration is coming at the wrong time; configuration blocks are supposed to appear before the script that loads MathJax.js itself, and different browsers act differently if that isn't the case. I see that MathView.js
is loaded after MathJax.js
, and that it calls MathJax.Hub.Register.StartupHook()
directly itself (that is, it doesn't make a MathJax configuration block). Since neither script call as the async
attribute, MathJax will load and begin running before MathView is even loaded. Depending on the state of the cache, and which browser you are using, MathJax may pause while loading a file, allowing MathView to load and run, and it may get its configuration in place before AsciiMath initializes itself; but I may not, and that is what you are seeing in the different cases. If you are using a late enough copy of MathJax (2.7.0 or later), then we could get this to work even as it stands, but earlier versions of MathJax contain a copy of AsciiMath that doesn't allow changes after it is initially loaded.
In any case, I think the way that MathJax is being handled in these pages may need to be rethought. Fir one thing, there are two script tags that load MathJax. While MathJax is smart enough to ignore the second call, it does cause some browsers to load the MathJax.js file more than once, which is inefficient.
MathJax can be configured to not do its start up until all the configuration has been completed, so it may be worth switching to that mode (it would also involve adding a call at the bottom of the page to tell MathJax that all the configuration is complete). Alternatively, more care could be made to insert the configuration as actual configuration blocks, and make sure they MathJax.js is loaded after that has occurred. That would take a little more care.
OK, for one thing, I pulled MathJax. It was on some 2.6 version.
The "free-standing" problem at my earlier link is loaded using the framework of webwork2/lib/WebworkClient/simple_format.pl
, which doesn't include anything for MathView in the distribution. But I have customized it to add the MathView css and js calls. (Perhaps this will ultimately be somewhere else than simple_format.pl
, but I'm experimenting.) After your message, I rearranged the order and deleted the extra MathJax call. And for good measure I enabled the delay until the configuration is complete. Things worked for me in Chrome and Firefox. After scrubbing Safari's cache, things work there too.
It's one thing to do this with simple_format.pl
, but will be at least a little harder over in webwork2/lib/WeBWorK/ContentGenerator/Problem.pm
, which builds the page for "regular" problems (as opposed to "free-standing"). But I think I can work on it now, leading to a pull request. For us at my school, I think MathView never took off because of the issues that started this thread. I'm hopeful that we're reaching a resolution now. It's too bad that it might come just as WIRIS enters the picture. But WIRIS is still commercial, so enhancements to MathView will be worth the effort.
Is there any downside to the delay-until-configured scheme?
Is there any downside to the delay-until-configured scheme?
Well, it does mean that MathJax won't start loading its dependencies (like the config file and any font files) until the end of the page is reached (as opposed to right away when its script tag is processed). But because WeBWorK problems are generally pretty short and don't have a lot of other scripts to load, I don't think this will be an issue. If there were lots of images, scripts, and other external resources, since most browsers limit the number of simultaneous connections they will make, it could mean Mathias has to wait for other content to arrive before it can start downloading its configuration and other files, and so delay the processing of Math.
That is really the only drawback that I can see. I think this is probably the easiest approach to getting git to work.
On the other hand, the MathView configuration is still technically being done in the wrong way, and you are relying on some delicate timing interactions to make it work. It is running in a jQuery ready function, and you are counting on MathJax having to wait for its configuration files and so on to cause a delay long enough to allow the ready function to run before MathJax does its configuration. There is no guarantee that that will happen.
It would be better if MathView.js would insert a <script type="text/x-mathjax-config">
containing its configuration (and do that outside of the ready function) so that the configuration is in place before the MathJax.Hub.Configured()
call is made. Currently, the MathJax.Hub.Configured()
call is coming before the MathView configuration is done (since the jQuery ready function won't fire until after that script is run), so you are really telling MathJax that the configuration is ready before it really is, and are relying on internal delays in MathJax to get it all to work.
I think this is probably the easiest approach to getting git to work.
Well, it seems like I have it working the way I want it to work for my server, but it feels fragile and not something I should commit and make a pull request for. The MathJax config is stored in a defaults.config variable,
$webworkURLs{MathJax}
. The default value is"$webworkURLs{htdocs}/mathjax/MathJax.js?config=TeX-MML-AM_HTMLorMML-full"
. So in localOverrides.conf, I changed it to"$webworkURLs{htdocs}/mathjax/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=configured"
.
But then there needs to be the call at the bottom of the page to signal the configuring is complete. The only place I could find to put this is in the math4 theme, in the system.template and gateway.template, where I put:
<footer>
<script type="text/javascript">
MathJax.Hub.Configured()
</script>
</footer>
And this is what I mostly don't feel good about. It's an important call to make that shouldn't be in the hands of a theme. Also, in math4 I see simple.template and lbtwo.template, which I don't know what these are for. But I added the footers there too. And then should I bother with math3? And what about schools that made their own theme copied from math4, that won't have the footer?
I'm going to see if I can get by with this for our server, but I don't think it is a real solution for everyone yet.
-- Alex Jordan Mathematics Instructor Portland Community College
It sounds like you have made good progress on this. I've looked through the webwork2 code, and there are 6 files that use the MathJax variable that you are changing:
webwork2/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm webwork2/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor2.pm webwork2/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor3.pm webwork2/lib/WeBWorK/ContentGenerator/Instructor/ProblemGrader.pm webwork2/lib/WeBWorK/ContentGenerator/Instructor/ShowAnswers.pm webwork2/lib/WeBWorK/ContentGenerator/Problem.pm
so one solution would be to modify these to include the MathJax.Hub.Configured() call. That could be done through another variable that defaults to blank, but that you override to include the call when you override the URL to include delayStartupUntil=configured. That is a bit inelegant, but would work.
One thing to note is that you should be able to put the MathJax.Hub.Configured() call into an onload handler, so you should not need to insert it at the bottom of the page directly. That means that those 6 files could have the Configured() call at the same location where the MathJax.js file is loaded.
There is an alternative, however, which is to replace the call to MathJax.js by a call to a separate .js file of your own that does two things:
1. Loads the actual MathJax.js file (by inserting a script that loads MathJax.js
2. Sets up the onload handler to call MathJax.Hub.Configure()
Then set $webworkURLs{MathJax} to point to your new .js file.
For (1), you could simply use document.write() to insert a script tag, but it is probably better to use document.createElement('script'), set the src attribute and then use document.head.appendChild() to insert it. Note, however, that this means MathJax will be loaded asynchronously, so you can't tell when the MathJax variable will be available. That means that code that refers to MathJax needs to be careful about how it does that. For example, the MathView.js file might need to be changed (I haven't looked at it this morning to check), since MathJax is not guaranteed to be available even when the onload event fires.
For (2), you would need to have the onload handler check for MathJax being available before calling MathJax.Hub.Configured, and if it is not available yet, you could either use setTimout() to try again in a bit, or use the alternative method of configuring MathJax by setting
window.MathJax = {
AuthorInit: function () {
MathJax.Hub.Configured();
}
};
so that when MathJax does load, it runs the AuthorInit function that indicates that MathJax is configured.
But I think there is an easier way (which I'm sorry I didn't think of earlier). There is another option for delayStartupUntil, which is delayStartupUntil=onload, which delays the configuration until the page's onload handler is fired. That should do what you need without requiring an explicit MathJax.Hub.Configured() call. I'm afraid I had forgotten about that option until just now when I was looking at the MathJax code to make sure the calling MathJax.Hub.Configured() from the AuthorInit function would be OK.
So I think if you just change to
"$webworkURLs{htdocs}/mathjax/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=onload";
that should be enough. In fact, it could easily be the default in defaults.config.
MathView is turning "in" into the "element of" symbol as in
\in
. So for example, a student typinginf
orinfinity
is seeing output of the form\in f
or\in f\in ity
.Not sure if it there are other scenarios as common as "inf", but it also does this for other strings. So if there were a string answer "topology", it is showing you output from
\top o\log y
.Is this just a configuration issue? If so, where is MathView configured?
Or maybe it's just assumed that with string answers, the student doesn't activate MathView?