brucemiller / LaTeXML

LaTeXML: a TeX and LaTeX to XML/HTML/ePub/MathML translator.
http://dlmf.nist.gov/LaTeXML/
Other
949 stars 101 forks source link

[Feature Request] Collapsible proofs #1834

Open FelixBenning opened 2 years ago

FelixBenning commented 2 years ago

Instead of

<div class="ltx_proof">
<h6 class="ltx_title ltx_runin ltx_font_italic ltx_title_proof">Solution.</h6>
...
</div>

What about

<details class="ltx_proof">
<summary class="ltx_title ltx_runin ltx_font_italic ltx_title_proof">Solution.</summary>
...
</details>

This would make proofs collapsible. Which seems like a really nice feature of html which you can not get in print.

FelixBenning commented 2 years ago

Alternatively this could be done with styling/javascript on the ltx_proof class (cf. https://www.w3schools.com/howto/howto_js_collapsible.asp)

dginev commented 2 years ago

@FelixBenning Your comment about CSS is indeed closer to what seems reasonable as I wouldn't expect proofs to be collapsible by default.

What we can consider is creating a separate CSS theme from scratch, following some guiding principles that go along with collapsible proofs. One can wonder what else may be collapsible, and where else one can save space. Maybe a "compact" theme?

FelixBenning commented 2 years ago

The disadvantage of the second solution is that it requires javascript and therefore is going to be unusable for people with script blockers. But I agree that it might be better to not force it to be collapsible by default. Another option would be to add the <details open> option. (cf. https://stackoverflow.com/questions/14286406/how-to-set-a-details-element-to-open-by-default-or-via-css)

But there should probably be a discussion about this.

FelixBenning commented 2 years ago

Thinking about it a bit more, what would be even cooler is, if you could select from a selection of proofs. E.g.

Or something like that. Definitely going to need classes in proof-divs #1835 for that. Or in the case of exercises hints or solutions. So I guess it does not really make sense to use the details/summary primitive...

btw. https://mannheim-probability.github.io/Probability-Theory/exercises/ thanks to you <3 Still a bit of a WIP though. Next step might be to have drop downs for the solutions. Some time in the future maybe have an exercise generator which asks you a question from an exercise pool and you can press a button for the solution.

FelixBenning commented 2 years ago
// collapsible_proofs.js

function changeTag (node, tag) {
    const clone = document.createElement(tag);
    for (const attr of node.attributes) {
      clone.setAttributeNS(null, attr.name, attr.value);
    }
    while (node.firstChild) {
      clone.appendChild(node.firstChild);
    }
    node.replaceWith(clone);
    return clone;
}

window.addEventListener("load", function() {
    const proofs = document.getElementsByClassName("ltx_proof");

    if(proofs.size != 0){
        for(let proof of proofs) {
            proof = changeTag(proof, "details");
            changeTag(proof.children[0], "summary");
            // ltx_runin adds display=inline CSS which removes the open arrow
            // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#customizing_the_disclosure_widget
            proof_name.classList.remove("ltx_runin");
        }
    }

})

This is my first attempt - kind of a hybrid, by attaching that with latexmlpost --javascript=collapsible_proofs.js you get collapsible proofs

dginev commented 2 years ago

Hi @FelixBenning ! I saw a recent stackexchange post of yours where you mention latexml can not be asked to put javascript at the end of the document. Actually, there is a way to request that nowadays, as a result of #1291 , namely:

--xsltparameter=LATEJS:true

Also, if you wanted to use latexml to provide custom markup modifications, you could inherit from the main XSLT toolchain and provide overriding/new rules. But that requires some comfort with programming XSLT, and we don't have any tutorials set up as of yet.

A third way is what I did for ar5iv, where I implemented rewrite rules in the language that served the HTML - Rust in that case. You could re-parse the HTML using a standard html/xml parser and select+modify via xpath, as one standard approach.

Let me know if that helps!

FelixBenning commented 2 years ago

@dginev oh wow, thank you! You are really going out of your way to help.

And so you do already use a templating language (i.e. XSLT)? That is nice! I don't know that language, but maybe I'll have a look at some point. Right now I ended up going down the lean4 rabbit hole because I wonder whether it is possible to check solutions automatically (i.e. have exercises, possibility to submit solutions, interactive hints, etc.) - the answer is probably no at the moment but it would be too cool 😂

FelixBenning commented 2 years ago

The maybeMathjax script is fine at the end right? It seems a bit unfortunate that you can only have all scripts at the end or none. But so far this works great :)

brucemiller commented 2 years ago

I believe in most (all?) cases, you can use the onload (or related) mechanism of javascript to avoid having to putting scripts at the end. And you probably should, as that seems to be a generally safer approach anyway.

And you do get usable classes on proof-like structures, if you use \newtheorem to define the environments.

As to the details & summary html elements, it sounds cool, but tricky to handle. In principle something could be turned into either a div+hn or details+summary in the XSLT. But in general, we wouldn't know which categories of things should be openable/closable, which ones should be initially open or closed, etc. One person wants theorems, one wants sections.

It's a shame that it apparently can't be achieved with pure CSS, would make it easy for an author to control with a simple --css=mydetails.css. We could provide something like the javascript you describe, but in general the user still would have to provide an extra bit of javascript to say which classes to apply it to, whether initially open or closed.

Trying to find that line between doing the Right thing generally, and making it as easy as possible to do Interesting things in special cases....

FelixBenning commented 1 year ago

Finally got around to converting my project into a template: https://github.com/Mannheim-Probability/Exercise-Sheets-Template I am not sure if I like it, it is a bit brittle and not pretty because there is basically no css. But maybe someone is inspired by it.

brucemiller commented 1 year ago

This is such a desirable category of feature that it's hard to dismiss. And yet HTML's details element is so limited, it's hard to see how best to make use of it in LaTeXML. It's the kind of feature that you might expect there to be a corresponding CSS display (or something), but there apparently isn't; it requires a bit of structured markup: a details/summary pair.

That structure is so suggestive! LaTeXML has many analogous structures of an element containing a title or tags which could reasonably be used as a summary, and I can imagine wanting many of them to be collapsible in some circumstance, sections, figures, tables, not just theorems. You could use a class to mark which ones to make collapsible, but making each one optionally convertible to details would put an awful lot of kludge into the XSLT.

Using javascript to massage the DOM is so much simpler, but does require javascript which some folks don't want. OTOH, I'd bet you'll end up wanting javascript anyway. With a similar feature in DLMF (the "info boxes") I found that I'd want the option to open or close all info boxes, or have their open state a bit sticky.

dginev commented 1 year ago

And yet HTML's details element is so limited, it's hard to see how best to make use of it in LaTeXML

Indeed. Looking towards the future, there is an active W3C community group called OpenUI (with at least one familiar face on it), which is doing some work to extend/upgrade the <details> capabilities. They had a recent call for community feedback on an "exclusive accordion" feature building on <details>, as explained in open-ui#812. So maybe even a declarative markup solution will one day become available, but not for a little while yet.

So probably a question of "when" rather than "if", given that everyone is fond of the general idea...

brucemiller commented 1 year ago

Interesting discussion! It almost seems that the problem is too many good solutions, with more to come, than there being no solution. I think, though, that at this point, it is premature to build anything into LaTeXML; certainly one can use javascript with the current code base.

So, I'm going to bump the milestone and see if a good general solution becomes clearer by then.