Background:
Here is how I am including the MathJax library in my page:
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML' async></script>
Problem:
The MathJax string (that I believe) will display what I want:
$$\sum_{s=1}^{1000} p_s \sum_{c=1}^{4} x_c$$
The closest MathJax string that I can get to work (display correctly):
$$\sum_{s=1}^{1000} p_s \sum_c^{4} x_c$$
As part of debugging, I have simplified the second summation down to 'x_c' but it still does not work. This leads me to believe that the problem is caused by the second summation index definition. When I try to add the 'c=1' bit to the second summation notation, it seems MathJax will no longer render the equation at all. This behavior seems strange since the first summation can have the defined index (e.g., 'i=1'). Any thoughts appreciated at this point.
As #Peter_Krautzberger has noted it looks like the Markdown parser has converted some text to italics. Which could be causing the issue.
The below snippet is to verify that the issue is not with MathJax.
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML-full&latest"></script>
$$\sum_{s=1}^{1000} p_s \sum_{c=1}^{4} x_c$$
According to https://divadnojnarg.github.io/blog/mathjax/ MathJax \sum_ does not work correctly in markdown and you have to use \sum\_.
Latex rendering errors
There are some differences with classical Latex expressions and the syntax to use in a markdown document. For example, \sum_ does not render with Hugo and you should use \sum_ instead (notice the second backslash before the underscore).
Try escaping the underscores.
Either:
$$\sum\_{s=1}^{1000} p\_s \sum\_{c=1}^{4} x\_c$$
or
$$\sum\_{s=1}^{1000} p_s \sum\_{c=1}^{4} x_c$$
Might do the trick.
There is also some additional config mentioned in the article that may be required:
<script type="text/javascript" async
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$','$'], ['\\(','\\)']],
displayMath: [['$$','$$']],
processEscapes: true,
processEnvironments: true,
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
TeX: { equationNumbers: { autoNumber: "AMS" },
extensions: ["AMSmath.js", "AMSsymbols.js"] }
}
});
MathJax.Hub.Queue(function() {
// https://github.com/mojombo/jekyll/issues/199
var all = MathJax.Hub.getAllJax(), i;
for(i = 0; i < all.length; i += 1) {
all[i].SourceElement().parentNode.className += ' has-jax';
}
});
MathJax.Hub.Config({
// Autonumbering by mathjax
TeX: { equationNumbers: { autoNumber: "AMS" } }
});
</script>
Related
This is treated as a XSS vulnerability issue. I'm using the redactor component from Imperavi, and it seems like it can't generate the right output value when the Html is not valid.
The problem is when we insert strings like this:
<<SCRIPT a=2>qssQ5GkdwWU=7;//<</SCRIPT>
The redactor removes the script tags and generates this string. This is expected because of XSS attacks.
<qssQ5GkdwWU=7;//<
The problem happens then the redactor tries to set the previous value to the redactor element using html.(html). It will think that there is an element and will output this:
<qssq5gkdwwu=7;> </qssq5gkdwwu=7;>
How can I set the value to the element but preventing this behavior?
You can override JQuery's htmlPrefilterfunction:
htmlPrefilter: function( html ) {
return html;
},
If special character are the issue then try escaping them like this:
// trying to set following string as innerHTML
let c = '<qssQ5GkdwWU=7;//<';
// with default jquery
$('.one').html(c);
// modify filter function, and do your own character escaping
jQuery.htmlPrefilter = function(html) {
let clean = html.replace(/[&<"']/g, function(m) {
switch (m) {
case '&':
return '&';
case '<':
return '<';
case '"':
return '"';
default:
return ''';
}
});
return clean;
}
// now try on second div
$('.two').html(c);
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
One:<span class="one"></span><br>
Two:<span class="two"></span><br>
Execute above script preferably before you load Redactor.
If you decide to do your own sanitization then you could use DOMPurify or similar library.
let content = 'Malicius content <img src="https://dummyimage.com/30" onload="this.style.border=`2px solid red`;alert(`attacked! :p`);" >';
// default jquery
$('.one').html(content);
// modify filter function, do your own sanitization
jQuery.htmlPrefilter = function(html) {
html = DOMPurify.sanitize(html);
console.log('sanitized: ', html)
return html;
}
// trying on second div
$('.two').html(content);
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.4/purify.min.js" integrity="sha512-jGh38w63cHRzfBHtyKgEMMkJswUFXDA3YXrDjaE8ptzxV5DDkLDUDjtGUy5tmDkOXHWsItKfFjocaEtj1WuVnQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
One:<span class="one"></span><br> Two:
<span class="two"></span><br>
First image gets red border. And because of the sanitization second doesn't.
I am creating a website in which I am trying to embed code blocks. Someone referred me to the CodeMirror library and thereafter I am trying to have some Javascript code in a code block .
I have incorporated the CodeMirror CSS and JS libraries into my HTMl
file and have created an instance of CodeMirror.
I managed to create a code block. But the code block doesn't apply any formatting/styling to the text in regards to whether it is Javascript or not
It just shows a code block with plain text. I have till now implemented the following code.
At the beginning I defined the following lines:
<link rel="stylesheet" href="codemirror-5.47.0/lib/codemirror.css">
<script src="codemirror-5.47.0/lib/codemirror.js"></script>
<script type="text/javascript" language="javascript">
window.load = function () {
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeeditor"), {
mode: "javascript",
lineNumbers: true
});
myCodeMirror.setSize(500, 300);
}
</script>
<textarea id="codeeditor" rows="20" cols="100">
var GetArray = function (Feature) {var dic = { "Bedrijfsvestigingen": ["bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_ALandbouw_BosbouwEnVisserij", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_B-fNijverheidEnEnergie", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_G_p_IHandelEnHoreca", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_H_p_JVervoer_InformatieEnCommunicatie", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_K-lFinancieleDiensten_OnroerendGoed", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_M-nZakelijkeDienstverlening", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_R-uCultuur_Recreatie_OverigeDiensten", "bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenTotaal"]};
</textarea>
The result is thus a code block with plain text and thus not formatting have been applied on JavaScript code. In case someone knows a solution to this problem, it would be nice to have a pure Javascript solution, since for example I am not familiar with jQuery for example.
You seem to have forgotten to import the "mode"-file; and probably some addons.
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeeditor"), {
mode: "javascript",
lineNumbers: true
});
//myCodeMirror.setSize(500, 300);
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.47.0/codemirror.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.47.0/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.47.0/mode/javascript/javascript.min.js"></script>
<textarea id="codeeditor" rows="20" cols="100">
var GetArray = function(Feature) {
var dic = {
"Bedrijfsvestigingen": [
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_ALandbouw_BosbouwEnVisserij",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_B-fNijverheidEnEnergie",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_G_p_IHandelEnHoreca",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_H_p_JVervoer_InformatieEnCommunicatie",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_K-lFinancieleDiensten_OnroerendGoed",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_M-nZakelijkeDienstverlening",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenNaarActiviteit_R-uCultuur_Recreatie_OverigeDiensten",
"bedrijfsvestigingen_Sbi2008_BedrijfsvestigingenTotaal"
]
};
}
</textarea>
I have a MathJax sample at Demo sample, which works as expected. All it does is typset the latex expressions within a div having an id of mathDiv.
I need to execute some custom logic when the third latex expression is about to be typset i.e. when ${ x } ^ { 4 } = 81 $ if $ x^4 - 9 =0 $ is going to be typset.
Question
Can I execute some custom JavaScript just before the above latex expression get typset by MathJax and if yes, then how would I do it?
I was thinking there might be some event model associated with MathJax typesetting, but couldn't find any in the docs.
The same demo sample code is as below.
<h2>Math Test</h2>
<div id="mathDiv">1. Solve for x $$X^2-1 = 8$$.
<br>2. Evaluate the following limit: $$\lim_{x \rightarrow b}{ (x-10) }$$
<br>3. Is ${ x } ^ { 4 } = 81 $ if $ x^4 - 9 =0 $ ?
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
</script>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script>
$(document).ready(function() {
MathJax.Hub.Queue(["Typeset", MathJax.Hub, "mathDiv"]);
});
</script>
There are signals for when math is typeset (see this example), though the signals for HTML-CSS output are a bit more complicate than for the other output formats.
But there is another approach that may work better for you. You can register a preprocessor that will run after the tex2jax preprocessor has located the math in the page, and that will put your wrapper around the math at that point. Then when the math is typeset, it will be inside the wrapper automatically.
Here is one example for that:
<style>
#math0 {color:red}
#math1 {color:blue}
#math2 {color:green; font-size: 200%}
#math3 {color:purple; font-size: 75%}
</style>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
MathJax.Hub.Register.PreProcessor(function (element) {
//
// Get the math scripts created by tex2jax
//
var math = element.querySelectorAll('script[type^="math/tex"]');
//
// Loop through them in reverse (since this
// is a live list)
//
for (var i = math.length - 1; i >= 0; i--) {
//
// Get the script and any preview that preceeds it
//
var script = math[i];
var preview = script.previousSibling;
if (preview && preview.className !== 'MathJax_Preview') preview = null;
//
// Create the wrapper span and give it an id
// (If you will be typesetting more than once,
// you will need to keep a global id number
// and use that rather than i)
//
var span = document.createElement('span');
span.id = 'math'+i;
//
// Insert the wrapper in place of the script
// and append the preview and script to
// the wrapper.
//
script.parentNode.replaceChild(span,script);
if (preview) span.append(preview);
span.append(script);
}
},50); // use priority 50 so it follows the standard MathJax preprocessors
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_CHTML-full"></script>
<h2>Math Test</h2>
<div id="mathDiv">1. Solve for x $$X^2-1 = 8$$.
<br>2. Evaluate the following limit: $$\lim_{x \rightarrow b}{ (x-10) }$$
<br>3. Is ${ x } ^ { 4 } = 81 $ if $ x^4 - 9 =0 $ ?
</div>
Here, the wrappers are styled to add color, and to scale the third and fourth expressions.
I hope the comments make it clear what is happening. This preprocessor will be run any time MathJax.Hub.Typeset() is called, so you can use that as normal.
Note that if the math is in the page initially, as it is here, there is no need to queue the Typeset() call by hand (as MathJax will typeset the page initially). If you are dynamically modifying the page, then you will need to do that.
I use RuleJS plugin for Handsontable (see it on GitHub) which works great for basic formulas but seems to lack recursive resolution.
I've made a code snippet containing two detailed examples, please check it out :
$(document).ready(function () {
var container1 = $('#example1');
var container2 = $('#example2');
container1.handsontable({
data: [[1, '=A2'], ['=B2', '=5 * 2']],
colHeaders: true,
rowHeaders: true,
formulas: true,
minSpareRows: 1
});
container2.handsontable({
data: [[1, '=A2', 3], ['=C1 * B2', '=5 + 1', 3]],
colHeaders: true,
rowHeaders: true,
formulas: true,
minSpareRows: 1
});
});
<!DOCTYPE html>
<html>
<head>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/jquery/jquery-1.10.2.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/handsontable/handsontable.full.js"></script>
<link rel="stylesheet" media="screen" href="http://handsontable.github.io/handsontable-ruleJS/lib/handsontable/handsontable.full.css">
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/lodash/lodash.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/underscore.string/underscore.string.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/moment/moment.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/numeral/numeral.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/numericjs/numeric.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/js-md5/md5.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/jstat/jstat.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/lib/formulajs/formula.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/js/parser.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/RuleJS/js/ruleJS.js"></script>
<script src="http://handsontable.github.io/handsontable-ruleJS/lib/handsontable/handsontable.formula.js"></script>
<link rel="stylesheet" media="screen" href="http://handsontable.github.io/handsontable-ruleJS/css/samples.css">
<style type="text/css">
body {background: white; margin: 20px;}
h2 {margin: 20px 0;}
</style>
</head>
<body>
<h2>Bugs in handsontable-ruleJS</h2>
<p>Both cases seem to come from the same problem, but they both worth seeing.</p>
<p>Here B1 displays the value of B2 <b>before</b> its interpretation where it should display "<b>10</b>". Just like it misses some recursive processing. Focusing the cell will show its real value "<b>=A2</b>" which will next be interpreted correctly.</p>
<div id="example1" class="handsontable"></div>
<p>This one is interesting, because when the cell "<b>A2</b>" tries to calculate "<b>C1 * B2</b>" it does "<b>3 * =5 + 1"</b> instead of "<b>3 * 6</b>", which obviously fails.</p>
<div id="example2" class="handsontable"></div>
<p>The only way to correct it is to edit "<b>C1</b>" (even without changing its value).</p>
</body>
</html>
If you prefer JSFiddle, here you go.
Best regards.
Edit: You may not see the first bug when using the embed snippet and going to fullscreen because it seems to trigger a refresh of the table. Use the JSFiddle for better results.
Edit 2 (SOLVED): Ok I think I've patched it, you can find the result here. I'll post a complete answer when Stackoverflow allows me to do it. Any feedback is still welcome, I'm sure there is a better way to do it but at least it seems to work now.
The working code can be found here : http://jsfiddle.net/71o23gp0/8/.
The important part was to replace :
var custom = {
cellValue: instance.getDataAtCell
};
By
var custom = {
cellValue: function(row, col){
var value = instance.getDataAtCell(row, col);
if (value && value[0] === '=') {
var formula = value.substr(1).toUpperCase();
var cellId = instance.plugin.utils.translateCellCoords({
row: row,
col: col
});
var item = instance.plugin.matrix.getItem(cellId);
if (!item) {
item = instance.plugin.matrix.addItem({
id: cellId,
formula: formula
});
} else {
item = instance.plugin.matrix.updateItem({
id: cellId,
formula: formula
});
}
var formulaResult = instance.plugin.parse(formula, {
row: row,
col: col,
id: cellId
});
value = formulaResult.result || '#ERROR';
formulasResults[cellId] = value;
instance.plugin.matrix.updateItem(item, {
formula: formula,
value: formulaResult.result,
error: formulaResult.error
});
}
return value;
}
};
Instead of simply returning the value of the cell, it checks if it's a formula and resolve it if so. Because this method is called by RuleJS when resolving a formula, this make the resolution recursive. The result is then cached for better performance.
There are other minor modifications in the source code, but I've added comments in the fiddle before and after every modification.
Following on from the answer https://stackoverflow.com/a/35528447/489865 in this question, I have patched a little further. The working code can be found at http://jsfiddle.net/ufL1vts5/.
The essential change is to store in formulasResults[] not just the "result" but rather the whole object returned by instance.plugin.parse(), so that cell highlighting for formulas is picked up, as per:
// parse formula
var newValue = instance.plugin.parse(formula, {row: row, col: col, id: cellId});
// cache result
formulasResults[cellId] = newValue;
My modifications include:
Store whole instance.plugin.parse() object in formulasResults[],
so that the formula/formula-error CSS style gets applied. [Note
that this is not perfect: it picks up "calculated" formula style
correctly, but sometimes what should be formula-error style only
get formula style --- but sufficient for my needs.]
Added formula & formula-error CSS styles (from supplied
handsontable.formula.css) into JSFiddle example, so that cell
highlighting can be seen.
Added 2 extra examples: one from
handsontable formula returning #NEED_UPDATE,
to show that works too, and one from the example supplied with
handsontable-ruleJS at https://github.com/handsontable/handsontable-ruleJS/blob/master/index.html.
Removed the newly added beforeRender hook via
instance.removeHook('beforeRender', beforeRender); in this.init = function ().
Changed some code layout in handsontable.formula.js, so that it
minimises the differences from that supplied with
handsontable-ruleJS.
This is my code:
<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/jquery.field.js" type="text/javascript"></script>
<script src="js/jquery.calculation.js" type="text/javascript"></script>
<script>
$(function() {
$('input[name^=sum]').keyup(function() {
var sum1 = parseFloat($('input[name=sum1]').val()) || 0;
var sum2 = parseFloat($('input[name=sum2]').val()) || 0;
var sum3 = parseFloat($('input[name=sum3]').val()) || 0;
$('#c_card_amount').val(sum1*sum3/100);
$('#total_inc_charges').val((sum1*sum3/100)+sum1);
});
});
</script>
In the input fields I would like to show the numbers in 1,000.00 format.
How can I format the numbers like this? Right now after the calculation numbers sometimes gets messed up like 452.25600000001. I would like to avoid that as well. Would be nice to rule the numbers properly.
Thank you for your help.
I recommend that you use NumberFormatter. Also you can see this question.
I would recommend you to try jQuery Format as mentioned in this question: Format numbers in javascript.
Below is an example of jQuery Format:
$.format.locale({
number: {
groupingSeparator: ',',
decimalSeparator: '.'
}
});
$.format.number(1000, '#,###.00'); // result: 1,000.00
$.format.number(452.25600000001, '#,###.00'); // result: 452.26
I would recommend you to use javascipt instead of jQuery. While jQuery made life more easy but don't forget that jQuery can be too large and your user have to load it on page while browsing.
Read this article for your answer http://www.mredkj.com/javascript/numberFormat.html