I use QWebEngineView to convert Markdown to HTML and render the math formula via MathJax. All the content are inside a <div id="placeholder">. Then I use document.getElementById("placeholder").innerHTML to get the HTML content, which contains the converted Markdown content and rendered MathJax output. At last, I output the HTML content to a HTML file.
However, when I open the exported HTML file via Chrome, the formulas lose the CSS styles like this demo.
So any idea to make the formulas in order?
I have tried to add MathJax script to the exported HTML but the formulas will disappear.
Thanks!
You need to grab not only the HTML, but also the CSS that MathJax's CommonHTML output jax produces, and the styles for the AssistiveMML extension (since your copied HTML includes its output as well). The code below will obtain it for you.
<script type="text/x-mathjax-config">
MathJax.Hub.Queue(function () {
var styles = document.head.getElementsByTagName("style");
styles = [].slice.call(styles); // convert to array
while (styles.length) {
var sheet = styles.pop();
if (sheet.innerHTML.match(/^(?:.mjx-chtml|.MJX_Assistive_MathML) \{/)) {
document.getElementById("sheet").innerHTML += sheet.innerHTML;
}
}
});
MathJax.Hub.Queue(function () {
var math = document.getElementById("math");
math.parentNode.removeChild(math);
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/MathJax.js?config=TeX-AMS_CHTML"></script>
<span id="math">\(x\)</span>
<pre id="sheet">
</pre>
Put this into a .css file an link that to your page (or put it into a <style> tag in the document head). That should do it for you.
Include the MathJax script in your HTML file:
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML'></script>
For some reason, the content is faded out and gets hidden, so the following styling is needed to stop the content from being hidden:
<style>
.MJXc-processed {
display: block !important;
}
</style>
You can add that inside the HTML file's head
Related
I would like to include in an html file, an external file that has math content that should be processed by MathJax. I tried a few ways to do this, and while the external file is being included in the html file, the math content in it is not processed. A minimal example to demonstrate this:
tst.html:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-chtml.js"></script>
</head>
<body>
This displays correctly: \(\phi\).
<inc></inc>
<script>
fetch("./tst.txt")
.then(response => {
return response.text()
})
.then(data => {
document.querySelector("inc").innerHTML = data;
});
</script>
<div id="abc"></div>
<div id="def">
<script>$("#def").load("tst.txt");</script>
</div>
<script>
$(function(){
$('#abc').load('tst.txt');
});
</script>
</body>
</html>
tst.txt:
\(\phi = 0\)
In the browser, the math content in the html file displays correctly, but not in the text from the included file . Is there a way to have the math content in the external file to be processed correctly?
Perhaps the issue is that the file is being pulled into the page only after MathJax has rendered the Maths. Therefore you would need to 'ask' MathJax to search through the page for any more Maths and render the new maths.
From MathJax documentation:
If you are writing a dynamic web page where content containing mathematics may appear after MathJax has already typeset the rest of the page, then you will need to tell MathJax to look for mathematics in the page again when that new content is produced. To do that, you need to use the MathJax.typeset() method. This will cause MathJax to look for unprocessed mathematics on the page and typeset it, leaving unchanged any math that has already been typeset.
I'm creating a widget that can be integrated by the third party with ease. What I need is to create a .js file and the user only needs to include that javascript file using <script> tags and the html tags gets rendered there.
ie.
example.com
widget.js
$(document).ready(function(){
render();
function render(){
return '<div>Html contents to be loaded</div>';
}
});
Third party file
thirdparty.html
<script src="http://example.com/widget.js"></script>
So while loading example.html how can I load all the html contents.
.append() should do the trick.
$(document).ready(function() {
$("body").append("<div>HTML here</div>");
});
Update: As there is no body tag, you could use .after().
$(document).ready(function() {
$("script").last().after("<div>HTML here</div>");
});
Remember to use .last() in case there is multiple script tags.
Back-story
I am creating a web application in which individual pages are "loaded" via the jQuery .load function. Originally the loaded page was a single file, but as it got longer I decided to split it into a .html file, a .css file, and a .js file.
Strangely, a single design flaw arose surrounding an element that was positioned using percentage values within the css. To see if I modified the styling while I moved, I replace the style tag (omitting the link tag instead) and it worked fine. Back and fourth a few times and I learned it was strictly occurring only when I used link tags rather than embedding it via style tags.
I wanted to use link tags, so I tried to narrow the problem down. After a while of fiddling, I traced it down to the .js file, specifically a usage of the .focus function on $(document).ready. If I comment out the .focus, everything works fine. Uncomment, and it breaks.
This appears to only happen in Chrome. It doesn't occur in FF26 or IE11.
Example
A fiddle.
Note that the problem only occurs in Chrome and that caching must be disabled. As Chrome's temporary cache disable doesn't extend into iframes of iframes, a direct result is easier to work with.
jQuery provides a callback function when the .load() method has completed and the DOM has been updated. This is where you would want to operate on elements that have been inserted from your external url.
<script>
$(document).ready(function() {
$('#content').load('html/portal.html', function() {
//now i can operate on elements loaded from html/portal.html
//they have been inserted into the DOM
$('input#input').focus();
})
});
</script>
As far as references to the link element, if you want to dynamically load a stylesheet from an external url using javascript you can employ a javascript function something like this:
//load deferred stylesheets
function loadStyleSheet(src) {
if (document.createStyleSheet) {
document.createStyleSheet(src);
} else {
$("head").append($("<link rel='stylesheet' href='"+src+"' type='text/css' media='screen' />"));
}
}
If you want to load an external javascript file you can use jQuery.getScript():
jQuery.getScript('/js/external.js');
So putting all of this together, if you want to load some content from an external resource, insert it into the DOM and the load an external stylesheet and an external javascript resource you could do so as follows:
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
$(document).ready(function() {
//function to load a deferred stylesheets
var loadStyleSheet = function(src) {
if (document.createStyleSheet) {
document.createStyleSheet(src);
} else {
$("head").append($("<link rel='stylesheet' href='"+src+"' type='text/css' media='screen' />"));
}
}
$('#someWrapper').load('external-url.html #someWrapper > *', function() {
loadStyleSheet('/css/external.css');
jQuery.getScript('/js/external.js');
})
});
</script>
</head>
<body>
<div id="someWrapper">
<!-- external content is loaded here -->
</div>
</body>
</html>
Here's what I'm trying to do;
I have this HTML code:
<div id="background-color-random">
DIV CONTENT
</div>
And this javascript:
$(document).ready(function() {
var colors = ["#FFA347", "#FF5050", "#FF66FF", "#6699FF", "#00FF99"],
selectedColor = colors[Math.floor(Math.random()*colors.length)]
header = $("div#background-color-random");
header.css("background-color", selectedColor);
});
I want to impliment this on an HTML page. I know that you can load up a *.js file by using the script tags with src="..". But that doesn't seem to work.
The javascript creates a random color and then applies that to the background of a given 'div' in the HTML.
Now, I'm not good with javascript, so please be patient with me and simple answers are needed :)
I need to be able to get the javascript to load when requested from the HTML and then apply itself to the div with id="..".
You have a syntax error (missing a comma):
selectedColor = colors[Math.floor(Math.random()*colors.length)]
header = $("div#background-color-random");
Should be
selectedColor = colors[Math.floor(Math.random()*colors.length)],
header = $("div#background-color-random");
You are using jQuery, not pure javascript. That's a good thing...
but you also must add the jQuery library in your head tags, like this:
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
You also need to put semi-colons (or commas, as RobM has corrected me, if between var assignments) at the end of each instruction. See line 3 in your code example.
If you want your js/jQuery code in a separate file, you can load the script code like this (again, usually done in the <head> tags):
<script src="filename.js" type="text/javascript"></script>
Or, you can include the js/jQ in the <head> tags of your document, like this:
<script type="text/javascript">
$(document).ready(function() {
var colors = ["#FFA347", "#FF5050", "#FF66FF", "#6699FF", "#00FF99"],
selectedColor = colors[Math.floor(Math.random()*colors.length)],
header = $("div#background-color-random");
header.css("background-color", selectedColor);
});
</script>
If including the script as an external file, you leave out the <script></script> wrapper from that file.
I have the following file file:
<html>
<head>
<title></title>
<script type="text/javascript" src="/Prototype.js"></script>
<script type="text/javascript">
function load_content()
{
new Ajax.PeriodicalUpdater('content', '/UpdatedContent/,
{
method: 'post',
frequency: 5
});
//var fileref = document.createElement("link");
//fileref.setAttribute("rel", "stylesheet");
//fileref.setAttribute("type", "text/css");
//fileref.setAttribute("href", filename);
}
</script>
</head>
<body>
<div id="content"></div>
<script type="text/javascript">
load_content();
</script>
</body>
</html>
Content from UpdatedContent is supposed to be loaded into the "content" div every 5 seconds. What's weird is that the HTML is loaded but the section at the top of the loaded page is completely stripped out when it gets inserted into "content"
The loaded page is essentially this:
<style type="text/css">
... lots of css here ...
</style>
... lots of HTML here ...
There are no , ,
Can CSS not be injected directly into a div?? Is there some reason either the Prototype framework or the browser's DOM is stripping out the CSS?
How can I include the CSS without making a separate call??
As you can see from the given main file, the page would be completely blank without anything loaded in the "content" div. This is intentional. I am basically wanting to use this as a structure on which to dynamically load updating content on an interval, so that the page doesn't have to completely reload to do a refresh of the data.
And no, I can't just hard code the CSS into the above file as the CSS will be changing too.
Edit: Regarding yaauie's response... now I know why it's happening, since I'm passing style and content in one single piece. If I separate the CSS into a separate file that can be loaded, how would I then load this via AJAX (preferrably using Prototype) and then, more importantly, set that CSS as the style sheet for the page content?
The <style> tag is only allowed in the <head> of HTML and XHTML, not the <body> or any of its descendants. Web browsers tend to be fairly forgiving of this in the initial parsing of a document, but when changing innerHTML I would expect that the browser would ignore any <style> elements because that type of element is not expected there.
As a workaround, would it be possible to use inline-CSS in your response, that is use the style="" attribute of the HTML elements you're passing?
EDIT: To add the CSS to the <head> would require one of two things:
Two round trips to your server:
A response that includes both and can be parsed before being inserted
In this case, I would recommend encoding your two parts into a JSON object before sending. Your callback on the AJAX action should split these and attach them to their appropriate locations (style first to avoid screen jitter)
{"style":"\ndiv#ajax7373 a {\n color:#fff;\n text-decoration:underline;\n font-weight:bold;\n \n}\ndiv#ajax7373 {\n background-color:#ff1cae;\n color:#ff6ccf;\n}","object":"\n<div id=\"#ajax7373\">\n\tThere is the contents of your div and a <a href=\"#\">link<\/a>\n<\/div>\n"}
That said, I find it hard to believe that the app favors style/content sepration so strongly and is employing a method where the style must generated by the content. Why not style the whole domain, including the expected return of your AJAX requests? Are the AJAX requested items really going to have enough variance in structure/style to warrant this?
You're stuck with either inline styles for the generated CSS or you'll have to write tons of class names for all the various styles you need so you can still separate out the styling. Then you could alter the class names via JS.