Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I display a proof tree with HTML,CSS and/or Javascript?

I want to display a proof tree in the style of a natural deduction within a web page. I will get the data from a JSON file.

Whats the best way to display something like this? Is it possible only with css? Or is there a library that can do something like this? Rendering as an image is not possible, because eventually it should be interactive. I should also mention that this tree can get fairly large.

Example: proof tree

Update: A better example of what the end result should look like: enter image description here

like image 525
schlicht Avatar asked Apr 25 '13 10:04

schlicht


2 Answers

The easiest solution would be mathjax which is a latex javascript renderer. And there are quite a few other similar rendering options out there.

Alternatively you could also look at MathML, which is the w3c standard for writing mathematical equations. Sadly, right now, the support for it is quite lacking as can be seen here, but long term it's going to be a great solution. Additionally the previously mentioned MathJax can be used as a MathML shim in browsers that do not support MathML yet.

The only concern with the MathJax shim is going to be that when you make it interactive it's going to interact differently with your code in browsers which do and do not support MathML, but despite that I would personally advice MathML except if you're already bound into LaTeX.

Based on your update I am not sure whether that can be expressed in MathML or LaTeX and I fear the only thing you could do is draw it on a canvas or set it up in a SVG if you need the interactivity later on. But I can warn you already know that that's not going to be a simple thing to do if you aren't used to it.


To add interactivity to Mathjax:

  1. Use MathML as input
  2. Use HTML/CSS as output
  3. Disable the MathJax context menu by adding showMathMenu:false to your core MathJax config
  4. Include id's in your MathML markup (literally <mo id="someid"> for example)
  5. Use for example jQuery to bind to the id after MathJax has finished (i.e. $("#someid").on("mousemove",function(){...}))

A fully working demo can be found here, move over the equal sign to trigger an alert.

like image 130
David Mulder Avatar answered Sep 25 '22 16:09

David Mulder


I came across the same thing recently, and I managed to write some CSS which gives quite good results I think. Here's a sample html skeleton:

<div class="proof">
    <div class="prems">
        <div class="proof">
            <div class="prems">
                <div class="proof">
                    <div class="prems">
                        <div class="proof">
                            <div class="concl">
                                <div class="concl-left"></div>
                                <div class="concl-center">bla</div>
                                <div class="concl-right"></div>
                            </div>
                        </div>
                        <div class="inter-proof"></div>
                        <div class="proof">
                            <div class="concl">
                                <div class="concl-left"></div>
                                <div class="concl-center">bla</div>
                                <div class="concl-right"></div>
                            </div>
                        </div>
                    </div>
                    <div class="concl">
                        <div class="concl-left"></div>
                        <div class="concl-center">bla</div>
                        <div class="concl-right"></div>
                    </div>
                </div>
                        <div class="inter-proof"></div>
                <div class="proof">
                    <div class="concl">
                        <div class="concl-left"></div>
                        <div class="concl-center">bla</div>
                        <div class="concl-right"></div>
                    </div>
                </div>
            </div>
            <div class="concl">
                <div class="concl-left"></div>
                <div class="concl-center">bla</div>
                <div class="concl-right"></div>
            </div>
        </div>
    </div>
    <div class="concl">
        <div class="concl-left"></div>
        <div class="concl-center">blabla</div>
        <div class="concl-right"></div>
    </div>
</div>

and here's the CSS:

.proof
{
    display: inline-flex;
    flex-direction: column;
}
.prems
{
    display: inline-flex;
    flex-wrap: nowrap;
    align-items: flex-end;
}
.inter-proof
{
    border-bottom: 1px solid black;
    width: 1em;
}
.concl
{
    display: inline-flex;
    margin-top: -1px;
}
.concl-left
{
    flex-grow: 1;
}
.concl-center
{
    border-top: 1px solid black;
}
.concl-right
{
    flex-grow: 1;
}
.prems > .proof:not(:first-child) > .concl > .concl-left
{
    border-bottom: 1px solid black;
}
.prems > .proof > .concl > .concl-center
{
    border-bottom: 1px solid black;
}
.prems > .proof:not(:last-child) > .concl > .concl-right
{
    border-bottom: 1px solid black;
}

see it live here. I only tried with firefox, and it may need some tweaks for other browsers.

like image 34
CSSproof Avatar answered Sep 22 '22 16:09

CSSproof