WeBWorK Main Forum

Modifying MathQuill to allow logarithms of arbitrary base?

Modifying MathQuill to allow logarithms of arbitrary base?

by Nathan Warkentin -
Number of replies: 7

Greetings:

Because I run a server and develop problems in a high school environment, I need to implement problems in logarithms for students who do not know how to change bases. I am working on a unit that introduces and reinforces the definition of logarithms as inverses of exponential functions, and it would be really helpful to allow students to enter logarithms of arbitrary base.

There are a couple of archived threads about implementing them directly. I've looked into it, and it seems extremely difficult, due to the underscore notation that LaTeX/MathQuill uses to denote bases. However, what if we just modified MathQuill to have a button for logarithms of arbitrary base (not unlike the button for roots of arbitrary order) which the parser interprets using a change of base (not unlike nth-roots, which the parser interprets as a fractional exponent)?

I do not know anything about MathQuill. It seems like the MathQuill implementation is local to WeBWorK. Is the creating of a new button something that I could do and test on my own server? If so, what is a likely resource that I could use to educate myself?

Thanks in advance!

In reply to Nathan Warkentin

Re: Modifying MathQuill to allow logarithms of arbitrary base?

by Glenn Rice -

I have attached what I do for this.  It uses a couple of my custom macros.  I will probably eventually add the macros to pg/macros.  They are in the attached zip.  You will need to place those into your courses macro directory.

I don't add a "log" button to MathQuill, but I add a subscript button.  Students can either type "log_5" or type "log" then click on the subscript button and then type 5 to enter the logarithm with base 5.

The bizarro stuff wouldn't be needed if you are just expecting answers of the form "log_5 3" for example.  It is needed for this problem because of the way it uses equality and the very basic nature of the problem.  For your situation this is probably a good problem though.

In reply to Glenn Rice

Re: Modifying MathQuill to allow logarithms of arbitrary base?

by Nathan Warkentin -
Thank you so much, Glenn! This is precisely what I was looking for. Ironically, much of the code that I was attempting to implement previously was very close to yours but was (naively) not included in a prefilter - that solves my problem precisely. I think that I will modify my implementation from yours, since I prefer to use the ImplicitEquation context with a custom answer checker (rather than your bizarro macro). I suppose I can always revert to bizarro math if I struggle too much with the implementation :)

Thank you for the reply; my perspective on problem authoring has been deepened. For posterity's sake, I will follow up with the code for my own implementation, once I am satisfied with it.
In reply to Glenn Rice

Re: Modifying MathQuill to allow logarithms of arbitrary base?

by Nathan Warkentin -
Glenn:

The parserLogb macro is great, and I am making really good progress. However, I cannot seem to add another button to MathQuill using the code that you placed inside RewriteExpAsLog.pg. Even just copying your problem file and the macros to my server without changes does not add a button. I have inspected the client side javascript elements, and the <script> tags are recognized by the browser; they just don't add another button. Can you please check the code, copied below?

TEXT(MODES(TeX => '', HTML => <<END_SCRIPT));
<script>
window.addEventListener('DOMContentLoaded', function() {
    if (window.answerQuills)
        answerQuills.$ans_name.buttons.splice(-5, 0,
            { id: 'subscript', latex: '_', tooltip: 'subscript (_)', icon: '\\text{\ \ }_\\text{\ \ }' });
});
</script>

My server is running WeBWorK 2.16, if it makes a difference.

As an aside, I believe that there was a typo in parserLogb.pl on line 83. One of the arguments of the Enable() routine was assigned the handle $complext rather than $complex, which would prevent enabling of complex-valued logs.
In reply to Nathan Warkentin

Re: Modifying MathQuill to allow logarithms of arbitrary base?

by Glenn Rice -

Thanks for pointing out the typo in the Enable() method.  That was a last minute edit.

The button should work on webwork 2.16.  You are calling "$ans_name = NEW_ANS_NAME();" earlier right?  That is critical.  You also have to use that as I did in the BEGIN_PGML/END_PGML part and in LABELED_ANS.

Actually there is one thing that has changed that might affect this. The loading of the JavaScript is now deferred, and I don't think it was in 2.16. So change the "DOMContentLoaded" event to the "load" event.

In reply to Glenn Rice

Re: Modifying MathQuill to allow logarithms of arbitrary base?

by Nathan Warkentin -

Thanks Glenn:

I apologize for my foolishness, but your button looked so similar to the superscript button that my eyes completely skipped over it when I was browsing. Your code works, even with the "DOMContentLoaded" event.

However, the subscript button just doesn't sit right with me. Since your solution was a fair hack, I decided to go full on and just modify /opt/webwork/webwork2/htdocs/js/apps/MathQuill/mqeditor.js in order to create a logarithm base b button. I have neither the time nor the programming chops to create a new LaTeX command for logb in MathQuill, so my compromise was to create a toggle in mqeditor.js which tells it to add a log button to the bar, and it creates a custom onClick event for that specific button in order to properly render a logarithm base b. Rather than post a file which may not be compatible with other versions of WeBWorK, here is the code in it that I changed.

<begin mqeditor.js - change code is underlined>
<snip>
    answerQuill.buttons = [
        { id: 'frac', latex: '/', tooltip: 'fraction (/)', icon: '\\frac{\\text{\ \ }}{\\text{\ \ }}' },
        { id: 'abs', latex: '|', tooltip: 'absolute value (|)', icon: '|\\text{\ \ }|' },
        { id: 'sqrt', latex: '\\sqrt', tooltip: 'square root (sqrt)', icon: '\\sqrt{\\text{\ \ }}' },
        { id: 'nthroot', latex: '\\root', tooltip: 'nth root (root)', icon: '\\sqrt[\\text{\ \ }]{\\text{\ \ }}' },
        { id: 'exponent', latex: '^', tooltip: 'exponent (^)', icon: '\\text{\ \ }^\\text{\ \ }' },
        { id: 'infty', latex: '\\infty', tooltip: 'infinity (inf)', icon: '\\infty' },
        { id: 'pi', latex: '\\pi', tooltip: 'pi (pi)', icon: '\\pi' },
        { id: 'vert', latex: '\\vert', tooltip: 'such that (vert)', icon: '|' },
        { id: 'cup', latex: '\\cup', tooltip: 'union (union)', icon: '\\cup' },
        // { id: 'leq', latex: '\\leq', tooltip: 'less than or equal (<=)', icon: '\\leq' },
        // { id: 'geq', latex: '\\geq', tooltip: 'greater than or equal (>=)', icon: '\\geq' },
        { id: 'text', latex: '\\text', tooltip: 'text mode (")', icon: 'Tt' }
    ];
    
    if(window.logb_button_toggle) {
        answerQuill.buttons.splice(-5, 0, { id: 'logb', latex: '\\log_', tooltip: 'logarithm base b (log_)', icon: '\\log_{\\text{\ \ }}(\\text{\ \ })' }); }


<snip>
$(".symbol-button").on("click", function() {
answerQuill.hasFocus = true;
if(window.logb_button_toggle && this.getAttribute("id") === 'logb'+ "-" + answerQuill.attr('id')) {
answerQuill.mathField.cmd('\\log');
answerQuill.mathField.cmd('_');
answerQuill.mathField.keystroke('Right');
answerQuill.mathField.cmd('(');
answerQuill.mathField.keystroke('Left');
answerQuill.mathField.keystroke('Left'); }
else
{ answerQuill.mathField.cmd(this.getAttribute("data-latex")); }
answerQuill.textarea.focus();
});
<no more changes until end of file>

In addition to this change, I also added the following code to the bottom of parserLogb.pl so that the toggle will be triggered anytime the parser is loaded. This has the added advantage of not forcing me to update every problem using this solution if the method of loading MathQuill ever changes - I can just work with mqeditor.js and parserLogb.pl.

main::POST_HEADER_TEXT(main::MODES(TeX=>"", HTML=><<"END_SCRIPT"));
<script> window.logb_button_toggle = true; </script>
END_SCRIPT


In conclusion, I would appreciate a warning if I have just done something that will cause major problems :)
In reply to Nathan Warkentin

Re: Modifying MathQuill to allow logarithms of arbitrary base?

by Nathan Warkentin -
It also occurs to me that I might not have to actually modify mqeditor.js in order to accomplish this goal. If I could somehow find an absolute reference for the logb button, I could also insert the code to modify its onClick behavior via the same process as I modified the toggle. Part of the button's ID is inherited from the answerQuill object, however. Is there a feasible way to accomplish this?
In reply to Nathan Warkentin

Re: Modifying MathQuill to allow logarithms of arbitrary base?

by Glenn Rice -

I am sorry, but I have to disagree with you here.  In my opinion the subscript button is better than a "logarithm with base b" button.  It teaches the students to put the logarithm with base b together in much the same way that it would be done in many computer systems.

Also, this should not be added to the mqeditor.js code in the way that you are doing.  That is certainly a massive hack.  Just add it as a button in your problem in the same way that I added the subscript button.  My method is not a hack.  It is how I designed things to work, and is documented at https://webwork.maa.org/wiki/NamedAnswerRules.