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:
Update: A better example of what the end result should look like:
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:
showMathMenu:false
to your core MathJax config<mo id="someid">
for example)$("#someid").on("mousemove",function(){...})
)A fully working demo can be found here, move over the equal sign to trigger an alert.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With