<!DOCTYPE html>
<head>
<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/2.0-beta/MathJax.js?config=TeX-AMS_HTML
">
</script>
</head>
<body>
<div style="width:400px; border: 1px solid black">
This is a div with small width containing math to be scaled to fit it.
<div id="dynamic" style="margin:1em 0; text-align:center">
\(\displaystyle x+x+x+x+x+x+x+x+x+x+x+x+x+x \)
</div>
</div>
<script>
MathJax.Hub.Queue(function () {
var math = document.getElementById("dynamic");
math.style.display = "inline"; var w = math.offsetWidth;
math.style.display = "";
if (w > 400) {math.style.fontSize = Math.floor(400/w * 100)+"%"}
MathJax.Hub.Queue(["Rerender",MathJax.Hub,math]);
});
</script>
</body>
No modifications are needed to MathJax, and you do not alter the
styles for any of MathJax's output. Instead, you use your own DIV
around the math to be adjusted (you can use a class to identify this
if you want, an use jQuery as in your own example. In order to get
the true width of the math, you use in-line mode with \displaystyle
instead. Then in your routine that determines the width, you
temporarily change the display CSS to inline (so it gets the natural
width) and then put it back to block after getting the width. If the
width is bigger than the container, you scale your DIV appropriately
and then re-render the mathematics using that scale (this step is not
absolutely required, but the results will be better if you re-render
it).
Note that you will need to have a container whose font-size you can
change (since each equation has its own scaling) and you can't use the
one produced by MathJax, since that will be removed and replaced by
the re-rendering. So using the extra DIV is really necessary and not
extra after all. The styling on the div is to replace the margin and
centering that the displayed equation would have had, since we use \
(\displaystyle ... \) rather than \[...\].
Finally, this approach will work no matter what rendering mode the
user has chosen, whereas solutions based on the MathJax_Display
element will only work with HTML-CSS output (the other renderers use
different classes for their output). It is best not to hack on the
HTML-CSS output itself, since that may change from version to version,
and it makes your results not work in NativeMML or SVG output.
In any case, this should point you in the right direction.
Davide
It is better not to edit the HTML-CSS jax.js file directly, but rather
use your configuration to modify it (people using the CDN don't have
access to do that anyway). For example
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
"HTML-CSS": {
styles: {
".MathJax_Display": {
width: null,
position: null,
display: "table"
}
}
}
});
</script>
would remove the width and position values and add the display:table
value that you want.
I don't recommend making this change, however, as this will affect not
only the math in the sidebar, but ALL displayed math. I'm not certain
what the effect of setting display:table will be in general.
Finally, your approach will only work for HTML-CSS output, not the
NativeMML or SVG output, and so if your user selects a different
renderer (or if the configuration chooses between NativeMML and HTML-
CSS (as most do), then you won't get the rescaling that you want.
So I recommend the example I sent earlier as a better method of
handling this.
Davide
Here is a modified version of your page.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML
">
</script>
<script>
function changeSize(button) {
var myeqn = document.getElementById('myeqn');
myeqn.style.fontSize = button.textContent;
MathJax.Hub.Queue(
['Rerender',MathJax.Hub,'myeqn'],
function () {
document.getElementById('mylabel').innerHTML =
'width: '+myeqn.offsetWidth+", height: "+myeqn.offsetHeight;
}
);
}
</script>
</head>
<body>
Font size:
<button onclick="changeSize(this)">x-small</button>
<button onclick="changeSize(this)">small</button>
<button onclick="changeSize(this)">medium</button>
<button onclick="changeSize(this)">large</button>
<button onclick="changeSize(this)">x-large</button>
<p id="mylabel"></p>
<span id="myeqn" style="border:thin solid red; display:inline-
block;width:auto;">
\(\displaystyle{\int_{-\infty}^\infty e^{-x^2}\, dx=\sqrt{\pi}}\)
</span>
</body>
</html>
I have put the re-rendering and measuring into one function called by
all the buttons. The key change, however, is that the looking up of
the size really should be part of the queued functions as well, since
the rendering may be asynchronous. Since the math has already been
rendered once, it is probably true that everything has already been
loaded, but it might be that a stretchy delimiter (for example) is at
a different size when the math is scaled, and that might require
loading a font, which is asynchronous. Or it might be that some other
piece of code is listening on the "New Math" signal that will be
generated when the math is rerendered, and that IT starts an
asynchronous action that you have to wait for. So you really do want
to have the size lookup in the queue as well so that you are sure it
isn't done until after the math is ready.
The inline-block is also a good choice. I had used inline because
only the width was of concern, but inline-block does give you both, as
you point out.
Davide
MathJax tries to match the ex-hight if its fonts to that of the
surrounding font, but it only has pixel-level resolution, so it may be
that MathJax can't resolve the difference between those two sizes in
the default font for your browser. You could try setting
<body style="font-size:200%">
and see if you get a better difference that way.
Davide
You might try making a div that contains the span and also some text,
and set its font-size (just using the inner span to measure the
mathematics) and see if the text is getting scaled properly (and to
see how well MathJax is matching the text).
Davide
OK, I thought they were relative, but I guess not (at least not in
some browsers).
>> You might try making a div that contains the span and also some text,
>> and set its font-size
>
> This was a bit more revealing: when I did this, the surrounding text
> behaved similarly to the MathJax -- the "large" size text font was
> heavier and a bit wider than the "medium" size, but not significantly
> taller. I'm sure MathJax is trying to find its size context from a
> height measurement (since that is the normal way to measure a font),
> so this would explain why the MathJax isn't changing much. It must be
> something about the default font settings for this browser, but I
> couldn't find anything unusual in the preferences.... Nothing that
> affects MathJax as a whole, to be sure.
Yes, MathJax tries to match the ex-height of its fonts with that of
the surrounding font. So if the surrounding fonts aren't changing
much, neither will MathJax's.
Davide
// resize all LaTeX Display elements to they fit in on screen
function cvonk_ResizeMathJax() {
jQuery('.MathJax_Display').each(function(ii, obj) {
var latex = obj.children[0];
var w = latex.offsetWidth;
var h = latex.offsetHeight;
var W = obj.offsetWidth;
if (w > W) {
obj.style.fontSize = 95 * W / w + "%";
}
});
}
window.MathJax = {
AuthorInit: function() {
MathJax.Hub.Register.StartupHook("Begin", function() {
MathJax.Hub.Queue(function() {
cvonk_ResizeMathJax();
});
});
},
jax: ["input/TeX", "output/HTML-CSS", "output/NativeMML"],
extensions: ["tex2jax.js"]
};
window.addEventListener("resize", function() {
cvonk_ResizeMathJax();
});