MathJax: hide math expression while processing - javascript

Im developing an application that shows a mathematical expression in function of the content of a form.
The webpage show the different states of the expression while its rendering, and I would like to show only the last state.
I have already hidden the mathematical expression while its shown in Tex language while MathJax is rendering.
But there are still two states more:
Processing: The expression is in a bigger font.
Typesetted: The final version, in a smaller font.
Im trying to hide one of them through:
Stopping MathJax before typesetting
or
Hide the expression while processing it
Is it possible?
This is the code to create the mathematial expression.
JAVASCRIPT
window.UpdateMath = function () {
values = document.getElementsByClassName('level');
arrayvalues = toArray(values);
var formula = "$10 \log (";
for (i = 0; i < arrayvalues.length; i++) {
if (i == 0){
formula = formula + " 10^{ \frac{" + arrayvalues[i] + "}{10}} ";
}else{
formula = formula + " + 10^{ \frac{" + arrayvalues[i] + "}{10}} ";
}
}
formula = formula + ")$";
document.getElementById('MathOutput').style.visibility = "hidden";
document.getElementById("MathOutput").innerHTML = formula;
//reprocess the MathOutput Element
MathJax.Hub.Queue(["Typeset",MathJax.Hub,"MathOutput"]);
MathJax.Hub.Queue(
function () {
document.getElementById('MathOutput').style.visibility = "";
}
);
}
})();
Full code here:
http://jsfiddle.net/AqDCA/888/

You want to turn off preprocessor previews and the fast previews. Try setting your configuration to this
MathJax.Hub.Config({
"fast-preview": {disabled:true},
tex2jax: {
preview: "none",
inlineMath: [["$","$"],["\\(","\\)"]]
}
});
This should make things work a bit more like what you want.

Related

How to fiil paragraph with content?

I want to create a paragraph that contains: name, cost (like "3.66$"). But the problem is that I want to fill the space in dots ("......") and I dont know how.
I take the values (name & cost) from database and each name is diffrent so I can not think about way that makes the space be filled with dots.
For instance, the rows:
"apple 20.58$"
"banana and ice cream 4.99$"
need to be:
"apple ...................... 20.58$"
"banana and ice cream ........ 4.99$"
this is the code:
for (var i = 0; i < data.d.length; i++) {
$(document).ready(function () {
$("#ShowMenu").append(
"<p style='text-align: left;margin: 0px;'>" +
"<span style='font-size: large;font-weight: bold;float:left;'>" + data.d[i].title + "</span>" +
"<span style='float:right;'>" + data.d[i].cost + "</span>" +
"</p>"
);
});
}
If you are replacing a value (and not a regular expression), only the
first instance of the value will be replaced. To replace all
occurrences of a specified value, use the global (g) modifier (see
"More Examples" below).
Souce.
The problem is that replace replaces the first found occurrence. You can do it like this:
function replaceAll(input, what, withWhat) {
while (input.indexOf(what) !== 0) {
input = input.replace(what, withWhat);
}
return input;
}
But this is not performant and not elegant. To improve it, you need to use regular expressions:
function replaceAll(input, what, withWhat) {
return input.replace(new RegExp(what, 'g'), withWhat);
}
and call replaceAll. If you want this to make it more general, you can do something like this:
String.prototype.replaceAll = replaceAll;
EDIT:
The answer above came from the assumption that the text is generated by Javascript. My assumption was wrong as can be seen from the comment section and the question edit. The real situation is that the spaces appear because of CSS styling with float.
A possible solution is to create an image of a dot character and another image with the desired background for the other contents. Set the background image of the paragraph to be the dot image with repeat and the background image of the span to be the colored image.
Another possible solution is not to use float, but to write the dots using javascript until the width is the desired one. This involves tag measuring and is slow.
You can use function like this:
function getReceiptItem(name, cost, maxLength) {
var dotsLength = maxLength - name.length - cost.length - '$'.length;
if (dotsLength < 0) {
name = name.substring(0, name.length + dotsLength);
dotsLength = 0;
}
return name + Array(dotsLength).join('.') + cost + '$';
}
Full example
Don`t forget set monospace font for receipt, like:
* {
font-family: 'monospace';
}

regexp looping and logic in javascript

Not certain if this can be done in regexp under javascript, but thought it would be interesting to see if it is possible.
So thought I would clean up a piece of html to remove most tags, literally just dropping them, so <H1><img><a href ....>. And that would be relatively simple (well, stole the basis from another post, thanks karim79 Remove HTML Tags in Javascript with Regex).
function(inString, maxlength, callback){
console.log("Sting is " + inString)
console.log("Its " + inString.length)
var regex = /(<([^>]+)>)/ig
var outString = inString.replace(regex, "");
console.log("No HTML sting " + outString);
if ( outString.length < maxlength){
callback(outString)
} else {
console.log("Lets cut first bit")
}
}
But then I started thinking, is there a way where I can control regex execution. So lets say that I want to keep certain tabs, like b,br,i and maybe change H1-6 to b. So in pseudo code, something like:
for ( var i in inString.regex.hits ) {
if ( hits[i] == H1 ) {
hits[i] = b;
}
}
The issue is that I want the text thats not HTML tags to stay as it is, and I want it to just cut out by default. One option would of course be to change the ones I want to keep. Say change <b> to [[b]], once that is done to all the ones of interest. Then put them back to <b> once all unknown have been removed. So like this (only for b, and not certain the code below would work):
function(inString, maxlength, callback){
console.log("Sting is " + inString)
console.log("Its " + inString.length)
var regex-remHTML = /(<([^>]+)>)/ig
var regex-hideB = /(<b>)/ig
var regex-showB = /([b])/ig
var outString = inString.replace(regex-hideB, "[b]");
outString = outString.replace(regex-remHTML, "");
outString = outString.replace(regex-showB, "<b>");
console.log("No HTML sting " + outString);
if ( outString.length < maxlength){
callback(outString)
} else {
console.log("Lets cut first bit")
}
}
But would it be possible to be smarter, writing cod ethat says here is a peice of HTML tag, run this code against the match.
As Tim Biegeleisen sai in its comment, maybe a better solution could be using a parser instead of a Regex...
By the way, if you want to control what is going to be changed by the regex you can pass a callback to the String.prototype.replace:
var input = "<div><h1>CIAO Bello</h1></div>";
var output = input.replace(/(<([^>]+)>)/gi, (val) => {
if(val.indexOf("div") > -1) {
return "";
}
return val;
})
;
console.log("output", output);

to apply sequential line numbering to lines in a paragraph: is it possible?

Is it possible to have jquery/javascript insert sequential line number at the start of all lines in a paragraph and, better still, to follow the sequence through to subsequent paragraphs?
I want to be able to refer students quickly to particular lines of an article (in a classroom setting). I have lots of articles to which I would like to apply this functionality, each of which has varying numbers of paragraphs.
I was hoping this might be possible, even in a responsive page, where the width of the paragraphs changes, depending on the display device, and the consequent number of lines in each paragraph becomes greater or fewer.
Thanks in advance to anyone who can help.
Here is one approach that may suit your purposes.
Get the height of a one-line paragraph, for reference.
For each paragraph, get the actual height, and infer the number of lines.
Loop through the lines and add the numbering at absolute positions.
var refHeight = $("p").eq(0).height();
$("p").eq(0).remove();
var cnt = 1;
$("p").each(function(index) {
var pos = $(this).position();
var h = $(this).height();
var lines = h / refHeight;
var lineHeight = h / lines;
for (var i=pos.top ; i<pos.top+h ; i += lineHeight) {
var num = $("<p>", { class: "number" });
num.text(cnt++);
num.css("top", i);
$(this).before(num);
console.log(i);
}
});
(Fiddle)
Edit
If you wanted to use a fixed line length (so that everyone is seeing the same numbers), you could combine the above with the following:
Break the paragraphs into lines.
Wrap each line in a span/div, and re-append.
Block the browser from text wrapping.
$("p").each(function() {
var text = $(this).text();
$(this).html("");
var i=0;
while (i<text.length) {
lineCharWidth = charWidth;
while (i+lineCharWidth < text.length && text[i+lineCharWidth] != ' ') {
lineCharWidth++;
}
var line = $("<span>", { class: "line" }).text(text.substr(i, lineCharWidth));
$(this).append(line).append("<br/>");
i += lineCharWidth;
}
});
(Fiddle)
Here's a solution that uses a function to split the paragraph text on space characters based on a pre-determined line length and then replaces the text with an <ol> comprised of <li> elements each containing one line of text:
var lineNum = 1;
function splitLines(text, lineLen) {
var words = text.split(/\s/g), line = '', lines = [];
$.each(words, function(idx) {
line += this + ' ';
if (line.length > lineLen || idx == words.length - 1) {
lines.push(line);
line = '';
lineNum += 1;
}
});
return lines;
}
$('p').each(function() {
var $p = $(this), $ol = $('<ol start="' + lineNum + '">'), lineLen = 50;
$.each(splitLines($p.text(), lineLen), function(idx) {
$ol.append('<li>' + this + '</li>');
});
$p.text('').append($ol);
});
I'm not sure about the support for the start attribute of the <ol>. It does work in Chrome. Even still, I like using the list element because it's a little more semantically meaningful, in my opinion.
Sure. Just make sure you're encoding your line returns and use it to split up the text with a simple replace.
Sample text:
The quick
brown fox
jumped over
the lazy dog
for this, the actual string would be the following:
The quick\r\nbrown fox\r\njumped over\r\nthe lazy dog
I think something like this would work (without the document.write, and there could be performance improvements):
var input = '\r\nThe quick\r\nbrown fox\r\njumped over\r\nthe lazy dog';
input = input.replace(/\r\n/g, '<div class=\'index\'></div>');
document.write(input);
var idx = 0;
$('.index').each(function(){
$(this).text(idx++);
});
If I'm not mistaken, this should write out an index number on each line. Could use some testing/debugging, though :)
For an example of how this is done, check out Github's diff pages.

eval javascript function IE6 taking long time

I have the below chunk of code. I've debugged through and located the snippet that is causing a long delay in IE6.
Basically the code loops through a document converting it to XML and sending to a PDF. On Ubuntu and Firefox 4 it takes 3 seconds. On IE it can take up to 40 seconds regularly.
/**
* This function builds up the XML to be saved to the DM.
*/
function getXMLToSave(){
var text="<workbook><sheet><name>Adv4New</name>";
//show_props(document.adv4.row10col1, "document.adv4.row10col1");
for(i=1;i<157;i++){
text = text + "<row number='" + i + "'>";
for(j=1;j<=7;j++){
text = text + "<col ";
//alert(eval('document.adv4.row'+i+'col'+j+'.readonly'));
try{
text = text + "number='" + j + "' label='" + eval('document.adv4.row'+i+'col'+j+'.className')+ "'";
}
catch (e) {
text = text + "number='" + j + "' label=''";
}
try {
if(eval('document.adv4.row'+i+'col'+j).readOnly)
text = text + " type='readonly'";
else
text = text + " type=''";
}
catch (e) {
text = text + " type=''";
}
try {
text = text + " color='" + eval('document.adv4.row'+i+'col'+j+'.style.color') + "'";
}
catch (e) {
text = text + " color=''";
}
text = text + ">";
try {
// don't wrap in a CDATA (like previously), but run cleanNode
// this fixes html entities
var content = eval('document.adv4.row'+i+'col'+j+'.value');
text = text + cleanNode(content);
}
catch (e) {
text = text + "0";
}
text = text + "</col>";
}
text = text + "</row>";
}
text = text + "</sheet></workbook>";
return text;
}
I believe its the eval function causing the delay in IE6. Is there a neat solution to fix this. Thanks very much
Why are you using eval in the firts place?
eval('document.adv4.row'+i+'col'+j+'.style.color')
Use bracket notation!
document.adv4["row"+i+"col"+j].style.color
You don't need eval() at all:
text = text + "number='" + j + "' label='" + document.adv4['row' + i + 'col' + j].className + "'";
Also, in IE6 (but not in newer browsers), building up large strings by repeatedly adding more content is really, really slow. It was way faster in that browser to build up strings by creating an array of substrings and then joining them all together when finished with all the pieces.
Don't use eval EVAL is EVIL. Having said that, you really shouldn't care about IE6: Even MS doesn't support it any longer, why should you bother?
Anyhow, change all eval calls like:
eval('document.adv4.row'+i+'col'+j+'.value');
to
document.adv4['row' + i + 'col' + j].value;
To access the elements directly. Remember that Nodes are objects, so their properties can be accessed either using the dot-notation (foo.bar) or the "associative array" notation: foo['bar'], the latter being very useful when you need the value of a variable to access properties
Don't use eval - period. The eval() should be renamed to evil(). There is almost no situation where you really need to use the eval function.
In this case you can use document.getElementById() to find a DOM node with a specific id.
It's likely that it's all the string concatentation that makes it slow. Each time you add something to the text, it will copy all the previous text into a new string.
Newer browsers have optimised code for this special case, so for them the impact is less.
Instead of concatenating strings like this:
text = text + "something";
use an array instead:
var text = [];
then add items to the array using the push method:
text.push("<workbook><sheet><name>Adv4New</name>");
Finally just join the strings together:
return text.join('');
One solution could be generating a color array (or maybe an object if you need it) and then using it.
But then, ask yourself the question "Should I really support IE6?"

javascript convert math text into latex/graphic

I am trying to find a plugin that can convert this text
1*2^3 + 0*2^2 + 1*2^1 = 1 + 0 + 3 = 5
into latex so it can be more easily readable and user friendly
I dont mind if i need to make simple modifications on the syntax...
If you only need a very basic markup, regular expressions are your friend.
The following example replaces each * with a middle dot · and adds some HTML markup (<sup>) to create those exponents. Of course this is just a very simple example that can be extended.
<span class="math">1*2^3 + 0*2^2 + 1*2^1 = 1 + 0 + 3 = 5</span>
<script>
(function(){
function convert(str) {
str = str.replace(/\*/g, "·");
str = str.replace(/\^(.)\s/g, "<sup>$1</sup> ");
return str;
};
var math = document.getElementsByClassName("math");
for (var i = 0, l = math.length; i < l; ++i) {
math[i].innerHTML = convert(math[i].innerHTML);
}
})();
</script>
Demo (JSFiddle)
However, as #Mathias suggested, MathJax is definitely worth a look if you want to display more complex mathematics.

Categories

Resources