PreTeXtBook / pretext

PreTeXt: an authoring and publishing system for scholarly documents
https://pretextbook.org
Other
254 stars 203 forks source link

Dynamic fitb #1931

Open dbrianwalton opened 1 year ago

dbrianwalton commented 1 year ago

Here is a pull request that will implement dynamic fill-in-the-blank (FITB) problems using a library for dynamic generation of mathematical expressions and the RunestoneComponents/fitb/ with added functionality that supports it. Functionality is dependent on a pending release by Runestone of an updated components library.

I tried to keep elements of different functionality in separate commits.

First commit: Editing text utilities that were going to be needed

Second commit: Implementation of the HTML version

Third commit: Additional modifications necessary to support the generation of static versions

Fourth commit: Addition of examples in sample article

New/Reuse of Tags (hopefully I remembered to list them all)

The structure of the xml defining the dynamic mathematical objects and the feedback is meant to be sandboxed away from the rest of the PreTeXt markup.

Note: The HTML support for also including JSXGraph natively (no i-frames to be connected to the dynamic content) in these exercises is ready but requires figuring out how this should integrate with the workflow for rendering static images.

dbrianwalton commented 1 year ago

Commit 08440a2: There was an evaluation error where a method was called at a state where that method was not valid. This was fixed. Also, the first example in the sample-article (find an interpolating cubic polynomial) could have random instances that were impossible to solve (root at x=0 and simultaneously asking for f(0)≠0). This required updating random routines to allow for dynamically determined end-points, which involved some new markup inside de-objects. (Updated javascript was updated to npm package btm-expressions@0.1.3 — relevant for Runestone side)

rbeezer commented 1 year ago

In part for my own benefit. To work with "test" JS from Runestone with this PR:

  1. Grab https://runestone.academy/cdn/runestone/test/webpack_static_imports.xml
  2. Place into your distribution at xsl/support
  3. Use string parameter: debug.rs.services.file support/webpack_static_imports.xml
rbeezer commented 1 year ago

OK, need some help. Was saving this for Friday Drop-In.

Seem the substitution file is sort of hollow, below. I see some of this stuff in the HTML output. I think the "regular" FITB in the sample book are broken (iirc), which I take as a sign that the new JS is in play?

Any thoughts? Walking through this at a Drop-In with screensharing would be fine - no rush on my end.

examples/sample-article/gen/dynamic_subs/dynamic_substitutions.xml

<xml><dynamic-substitution id="dynamic-fitb-simple-formula"><eval-subst expr="x1">[%= toTeX(x1) %]</eval-subst>
<eval-subst expr="x2">[%= toTeX(x2) %]</eval-subst>
<eval-subst expr="x3">[%= toTeX(x3) %]</eval-subst>
<eval-subst expr="y0">[%= toTeX(y0) %]</eval-subst>
<eval-subst expr="base_cubic">[%= toTeX(base_cubic) %]</eval-subst>
<eval-subst expr="base_yint">[%= toTeX(base_yint) %]</eval-subst>
<eval-subst expr="y0">[%= toTeX(y0) %]</eval-subst>
<eval-subst expr="base_cubic">[%= toTeX(base_cubic) %]</eval-subst>
<eval-subst expr="y0">[%= toTeX(y0) %]</eval-subst>
<eval-subst expr="A">[%= toTeX(A) %]</eval-subst>
<eval-subst expr="cubic">[%= toTeX(cubic) %]</eval-subst>
</dynamic-substitution><dynamic-substitution id="function-decomposition"><eval-subst expr="composition">[%= toTeX(composition) %]</eval-subst>
<eval-subst expr="innerFormula">[%= toTeX(innerFormula) %]</eval-subst>
<eval-subst expr="innerFormula">[%= toTeX(innerFormula) %]</eval-subst>
<eval-subst expr="innerFormula">[%= toTeX(innerFormula) %]</eval-subst>
<eval-subst expr="outerFormula">[%= toTeX(outerFormula) %]</eval-subst>
</dynamic-substitution></xml>
bnmnetp commented 1 year ago

I might expect the statement to be missing, but I would have thought the old fitb would continue working... @bjones1 ?? Did more of the json change than just adding in the html to the json?

@rbeezer here is the html that the runestone build generates for fill ins currently, and they are working on my overview build....

<div class="runestone">

   <div data-component="fillintheblank" data-question_label="2.2.1" id="fill1512"  style="visibility: hidden;">
   <script type="application/json">
   {"problemHtml": "<p>How many bowling pins are used when bowling?\nYou can put spaces before or after the number without affecting\nthe correctness of the answer.\nYou can provide the answer in decimal (10), hexadecimal (0xA),\nbinary (0b1010), or using scientific notation (1e1).</p>\n<input type=\"text\" name='' />", 
"dyn_vars": null, 
"blankNames": {}, 
"feedbackArray": [
  [{"number": [10, 10], 
     "feedback": "<p>Correct.</p>\n"}, 
   {"number": [16, 16], 
    "feedback": "<p>Incorrect. (Note that solutions can be provided in any base\nas well).</p>\n"}, 
   {"regex": "^\\s*.*\\s*$", 
    "regexFlags": "", 
     "feedback": "<p>Incorrect. Note that the last option given, regardless of\nits content, matches any response not already matched by\nthe previous feedback options. For example, <code class=\"docutils literal notranslate\"><span class=\"pre\">:x:</span></code> would\nwork in the same way.</p>\n"}
  ]]}
   </script>
   </div>
   </div>
    
dbrianwalton commented 1 year ago

There was an error on my code because I had not accounted for the included javascript to be minified and used a constructor name as a literal. There should be an updated package on npm where that issue is fixed @.***). An updated test release on Runestone should resolve that.

The fact that anything at all was saved in the substitutions file means the updated RunestoneComponents fitb was being applied. But the error mentioned above prevented any actual dynamic calculations to take place. I wasn't aware that old-style FITB wouldn't work. I haven't looked at that.

On Mon, Feb 20, 2023 at 11:38 AM Bradley Miller @.***> wrote:

I might expect the statement to be missing, but I would have thought the old fitb would continue working... @bjones1 https://github.com/bjones1 ?? Did more of the json change than just adding in the html to the json?

@rbeezer https://github.com/rbeezer here is the html that the runestone build generates for fill ins currently, and they are working on my overview build....

``

— Reply to this email directly, view it on GitHub https://github.com/PreTeXtBook/pretext/pull/1931#issuecomment-1437293592, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARCEJLM3XS2XARJHOQ7NYTWYOMYHANCNFSM6AAAAAAUXKUGFI . You are receiving this because you authored the thread.Message ID: @.***>

bnmnetp commented 1 year ago

Which package do I need to update?

dbrianwalton commented 1 year ago

I don't know why replying by email obscured the name of the package. btm-expressions version 0.1.3 had the error, and 0.1.4 should have fixed it.

bjones1 commented 1 year ago

I might expect the statement to be missing, but I would have thought the old fitb would continue working... @bjones1 ?? Did more of the json change than just adding in the html to the json?

No, but the "new" fitb setup requires the HTML for the problem (even for non-dynamic problems) to be placed in the problemHtml entry of the JSON data. The old FITB setup put this data directly into the HTML of the problem. So, we do need a tweak on the PreTeXt side to account for this -- @dbrianwalton?

rbeezer commented 1 year ago

Another attempt at this, prior to to today's Drop-In. Substitutions file is now smaller for me and Playwright is not finding the Not sure what needs to change in response to discussion:

This can wait for Drop-In...

bjones1 commented 1 year ago

Thanks for taking a look. Yes re: problemHtml key, but I haven't looked at that source to determine where to change it. I'm guessing @dbrianwalton would know this code fairly well. I should be there for (part of) the drop-in.

dbrianwalton commented 1 year ago

The test archive on RS CDN is not yet updated to pull in the updates on the btm-expressions javascript code. It is seeing v0.1.3. With an update today to remove a toString method on BTM class, this now should see v0.1.5.

The "problemHtml" key also needs to be worked through to ensure that old-style FITB problems work. That's really part of what is needed to resolve the complementary RunestoneComponents pull request.

rbeezer commented 1 year ago

Thanks for the updates! Keep me posted here?

rbeezer commented 1 year ago

I have "new" JS from Runestone, and working with latest branch here. Using pretext/pretext to get the dynamic component.

See log below.

I see div.dynamic-fitb-simple-formula in an INFO message and it seems to exist on the page.

However playwright seems to say it cannot find div.dynamic-fitb-simple-formula-substitutions. I see this on the page, but it seems to be buried inside the JSON blob? Is there a mismatch?

Off to try a brute-force hack...

Rob

PTX:DEBUG   : Using http.server subprocess 1006023
PTX:INFO    : Storing dynamic substitutions in file /home/rob/mathbook/mathbook/examples/sample-article/gen/dynamic_subs/dynamic_substitutions.xml
PTX:INFO    : extracting substitutions for exercise with identifier "dynamic-fitb-simple-formula" on page http://localhost:8888/dynamic-fitb-simple-formula.html
PTX:INFO    : Closing http.server subprocess
PTX:DEBUG   : Log data from http.server:
PTX:DEBUG   : 127.0.0.1 - - [24/Feb/2023 09:44:14] "GET /dynamic-fitb-simple-formula.html HTTP/1.1" 200 -
PTX:DEBUG   : 127.0.0.1 - - [24/Feb/2023 09:44:15] "GET /external/misc/book-cover-google-art-project.jpg HTTP/1.1" 200 -
PTX:DEBUG   : 
Traceback (most recent call last):
  File "/home/rob/mathbook/mathbook/pretext/pretext", line 817, in <module>
    main()
  File "/home/rob/mathbook/mathbook/pretext/pretext", line 694, in main
    ptx.dynamic_substitutions(
  File "/home/rob/mathbook/mathbook/pretext/pretext.py", line 1124, in dynamic_substitutions
    asyncio.get_event_loop().run_until_complete(extract_substitutions(dynamic_exercises, baseurl, dyn_subs_file))
  File "/usr/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
    return future.result()
  File "/home/rob/mathbook/mathbook/pretext/pretext.py", line 1036, in extract_substitutions
    exercise_substitutions = await elt.inner_html()
  File "/home/rob/mathbook/python-virtual/rab/lib/python3.10/site-packages/playwright/async_api/_generated.py", line 16047, in inner_html
    return mapping.from_maybe_impl(await self._impl_obj.inner_html(timeout=timeout))
  File "/home/rob/mathbook/python-virtual/rab/lib/python3.10/site-packages/playwright/_impl/_locator.py", line 386, in inner_html
    return await self._frame.inner_html(
  File "/home/rob/mathbook/python-virtual/rab/lib/python3.10/site-packages/playwright/_impl/_frame.py", line 615, in inner_html
    return await self._channel.send("innerHTML", locals_to_params(locals()))
  File "/home/rob/mathbook/python-virtual/rab/lib/python3.10/site-packages/playwright/_impl/_connection.py", line 44, in send
    return await self._connection.wrap_api_call(
  File "/home/rob/mathbook/python-virtual/rab/lib/python3.10/site-packages/playwright/_impl/_connection.py", line 419, in wrap_api_call
    return await cb()
  File "/home/rob/mathbook/python-virtual/rab/lib/python3.10/site-packages/playwright/_impl/_connection.py", line 79, in inner_send
    result = next(iter(done)).result()
playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for locator("xpath=//div[@id='dynamic-fitb-simple-formula-substitutions']")
============================================================
rbeezer commented 1 year ago

Off to try a brute-force hack

Maybe not so fast, I see how that -substitutions div might get rendered onto the page for playwright to find.

rbeezer commented 1 year ago

And a rendering of dynamic-fitb-simple-formula.html from the temporary directory fails to show an exercises. Inspector says:

GEThttps://runestone.academy/cdn/runestone/test/runtime.8f782b49f25513.bundle.js
[HTTP/1.1 404 Not Found 398ms]
rbeezer commented 1 year ago

Over the hump. Runestone CDN had it wrong. Substitutions finish normally. Onward.

rbeezer commented 1 year ago

Alright! I'm getting dynamic problems and a nice PDF version. Very good. So I am finally in a position to test thoroughtly and review (but maybe not this morning). Thanks.

bjones1 commented 1 year ago

Wow, fantastic! Very exciting! Let me know if I can help on the JavaScript side.

rbeezer commented 1 year ago

I've been tninking you might be making some changes? (A force-push is fine.)

Or is the ball in my court?

dbrianwalton commented 1 year ago

It has been in my court, but schedule was particularly busy.

I believe I have the HTML version working now with the static and dynamic styles. I have included rewrites of the static fitb examples from sample-book and have them working in a modified sample-article for testing purposes. I think you (@rbeezer) were saying that you would be able to write the preprocessor that could go from the old markup to this new style?

A push of this update will be posted shortly. I have not yet gone back through to see about the static output, but wanted to get this uploaded for you to look at.

bnmnetp commented 1 year ago

@dbrianwalton I cannot recreate the problem on the page you linked to. It was shortly after your post that I made the most recent fixes. I see the current implementation of the fillins does not use the prescribed pattern, so I don't imagine your new code does either.

dbrianwalton commented 1 year ago

The issue I raised (#1967) was not actually about this pull request, but was discovered while I was working on this pull request, and so I don't think has anything to do with the fillin code.

dbrianwalton commented 1 year ago

I discovered that the Runestone Services file that is available right now for testing this branch (https://runestone.academy/cdn/runestone/test/webpack_static_imports.xml) has a typo inside.

It says to use runtime.8fe782b49f25513.bundle.js but the directory listing indicates this should have been runtime.8fe5782b49f25513.bundle.js. Note the first four/five characters of the hash: 8fe7 vs 8fe57.

Referencing @rbeezer's note above, if the file is downloaded as currently stands, then the line can be edited to add the missing 5 and get the components to successfully load.

bnmnetp commented 11 months ago

Hey @dbrianwalton I have a group of authors that are very eager for this PR to be merged. What can I do to help make that happen?

dbrianwalton commented 11 months ago

I had thought this was left at a point where it was waiting for @rbeezer to do some review, and then he had a series of other responsibilities that he wasn't able to look through things until later. One of the issues was that there was a typo regarding which runtime.bundle.js was being used (see my comment before this). I don't know if that was addressed. Otherwise I have been thinking that it was on Rob's side of things. I've been sidetracked on various department responsibilities and otherwise should have followed up.

bnmnetp commented 11 months ago

Thanks @dbrianwalton

The "typo" may have been a typo at one point because you may have gotten a hand edited version.... but the webpack_static_imports.xml file gets updated automatically with every release of the runestone components. That is working just fine for all our builds.

I'll talk with @rbeezer about this some more during drop in today.

Thanks for the update.

dbrianwalton commented 11 months ago

This is what I meant:

I followed @rbeezer's comment from Feb 17: 1) Grab https://runestone.academy/cdn/runestone/test/webpack_static_imports.xml 2) Place into your distribution at xsl/support 3) Use string parameter: debug.rs.services.file support/webpack_static_imports.xml

I then process my XML using pretext with the appropriate string parameter to create HMTL files. When I open the HTML in my browser, the fillin problems don't work. Actually all of the Runestone components fail to work.

The browser develop tools reports an error: "Failed to load resource: the server responded with a status of 404 (Not Found)" and the resource it was trying is "https://runestone.academy/cdn/runestone/test/runtime.8fe782b49f25513.bundle.js" That file name comes from the webpack_static_imports.xml.

When I went digging in the actual folder I saw that the name of the file is missing a single character in the hash. Instead of starting "8fe78" it is supposed to start "8fe573". Adding the character in name stored in my downloaded copy of webpack_static_imports.xml gets things working again.

I don't know where to post this as an error for the server.

dbrianwalton commented 11 months ago

@rbeezer I tried to put together a possible xsl conversion that would take the style of FITB using "var" to the new version using "fillin" and with the revised evaluation block in place of what used to be setup. That is found in xsl/pretext-assembly.xsl. I tried to make it so that other uses of var don't get touched. This is what commit ec8fefb attempts.

For reference, there are (temporarily) the old problems that were in sample-book/rune.xml copied into sample-article/sample-article.xml next to my new problems but directly coded in the new style. It is not my intention of leaving those in the sample article, but you had suggested having examples of the old problems as they would be coded now.

bnmnetp commented 11 months ago

OK, @dbrianwalton that was so long ago, I'm surprised that test hasn't been overwritten many times, but the typo is just a typo on my part in trying to get things set up for you. I've modified the webpack_static_imports.xml to fix that typo. It is not a server problem. Just a problem with trying to hack something for you to test with that I long since forgot about.

Sorry for the confusion.

Brad

bjones1 commented 6 months ago

Per @rbeezer's email, is still dead or alive? Doenet seems like a great alternative to this; unless @dbrianwalton wants to keep going on this, I'd suggest closing this PR.

dbrianwalton commented 6 months ago

I've been unable to attend the break-outs. What email did I miss? I haven't seen any activity from Rob and figured he had other more pressing things on the plate.

On Tue, Oct 24, 2023 at 3:03 PM Bryan A. Jones @.***> wrote:

Per @rbeezer https://github.com/rbeezer's email, is still dead or alive? Doenet seems like a great alternative to this; unless @dbrianwalton https://github.com/dbrianwalton wants to keep going on this, I'd suggest closing this PR.

— Reply to this email directly, view it on GitHub https://github.com/PreTeXtBook/pretext/pull/1931#issuecomment-1777853425, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARCEJMUZRELZVJXA7DBWELYBAGH3AVCNFSM6AAAAAAUXKUGFKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZXHA2TGNBSGU . You are receiving this because you were mentioned.Message ID: @.***>

dbrianwalton commented 1 month ago

I have been working through the dynamic fitb exercises to rebase on master. I'm a little scared to just force my rebased code to the original branch and so created a new branch dynamic-fitb-rebased on my repo.

Key changes from the rebase:

In my own verification of the code, my computer is stuck on FontAwesome missing when generating PDF, but the LaTeX file looks good. I think the PreTeXt side is working.

dbrianwalton commented 1 month ago

I did notice that I am creating a TypeValue error on the Runestone logging side because my object that stores the mathematical expressions has an environment variable for the math environment is referenced within objects in its own catalog of known expressions. This creates a circular reference that JSON doesn't like when the object is being stored in the log. I will want to see how to avoid this issue so that the Javascript console is clear of any errors — the object does not need to be stored, but the code just pushes everything in anyway.

dbrianwalton commented 1 month ago

@bjones1 I'm hoping to get this PR finished. It is going to require updating/recreating the necessary PR on the RunestoneComponents side based on the current state of that project. Are you able to spearhead that task? (I'm verifying some changes to the btm-expressions library that will eventually need to be linked in on that side.)

bjones1 commented 1 month ago

Unfortunately, no. The work I did on the Runestone side was done before the big code reorg, and would probably require re-implementing this entirely, plus need a lot of buy-in from @bnmnetp. My time is pretty committed on other projects, sadly.

bnmnetp commented 1 month ago

@bjones1 The structure of the code for the components is essentially unchanged. It lives in a new place in the monorepo but everything below the runestone folder is identical.

The PR would somehow need to be moved to the new repo.

I don't really remember how "fully baked" the runestone side of the PR was.

bjones1 commented 1 month ago

Brad, thanks. That might make the task a lot easier. I'll look to see the difficulty involved to retarget the PR.

dbrianwalton commented 1 month ago

@bjones1 I have just made a PR to the Runestone rs repository that I believe implements all of the items that you had in the original repo. Hopefully that helps.

@rbeezer Would you like me to create a new PR based on the updated current status of Pretext and close this one out?

rbeezer commented 1 month ago

create a new PR based on the updated current status of Pretext

It'd be nice to keep all the discussion here. Can you force-push a new version of the branch, emanating from someplace close to the current head?

dbrianwalton commented 1 month ago

I have made the force-push. The underlying Runestone javascript that this is based on is no-longer supported by the test repository that was made two years ago. It can be created using https://github.com/RunestoneInteractive/rs/pull/476 and following the _static instructions https://runestone-monorepo.readthedocs.io/en/latest/javascript_feature.html.

I'm not sure how best to proceed at this point. What can I do next?

rbeezer commented 4 weeks ago

Dear Brian,

Took this for a spin today. Without looking too hard, everything procedural looks fine. In other words, I can rebase onto master, build the sample BOOK for non-RS-hosted HTML and all seems well. I've not gone as far as to enable the new JS.

Brad and I have talked about this some. Getting PreTeXt, Runestone, and this PR all tested and coordinated at one time might be trouble asynchronously. What do you think about using physical proximmity to our advantage when in Tacoma? That's valuable time, but this is worth it. And Brad and I could do some further testing/review you might suggest that would get us best-prepared for that.

Rob