Render math with KaTeX in the browser - javascript

I am using KaTeX to render math in the browser.
Right now I am using something like
document.getElementById('el').innerHTML = function () {
const span = document.createElement('span');
katex.render('2+\frac{1}{x}', span);
return span.innerHTML;
});
but it seems really stupid that I have to apply it to an element, and then take the html from this element and insert in my string.
I have looked through the KaTeX documentation, but I cannot find anything to help me just rendering some text directly in the browser with something like katex.render('2+3+4').

I don't know if you're still looking for an answer but maybe this will be helpful.
First, I link to katex.min.js and katex.min.css from a cdn.
I wrap everything I want rendered in katex inside span tags and give them the class 'math'
For example:
<span class='math'>2+\frac{1}{x}</span>
Then inside a pair of script tags I include something like this:
var math = document.getElementsByClassName('math');
for (var i = 0; i < math.length; i++) {
katex.render(math[i].textContent, math[i]);
}
So as long as I write my math text inside an element with the class math, it gets rendered by katex.
EDIT: We should use textContent instead of innerHTML. I've run into issues using innerHTML. See using katex, '&' alignment symbol displays as 'amp;'

Use KaTeX's auto-render extension, which will let you add your KaTeX directly to the HTML with a delimiter like $$ and then render it all at once:
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/contrib/auto-render.min.js"></script>
</head>
<body>
<div id="el"><span>$$2+\frac{1}{x}$$</span></div>
<script>
renderMathInElement(document.body);
</script>
</body>
</html>

Related

Is it possible to use javascript to modify a script element?

Is there a way to use javascript to modify a script element?
Like for example:
HTML:
<script id="something" src="/js/file.js"></script>
Javascript:
var something = document.getElementById("something");
something.src = "/js/anotherfile.js"
Is it possible? Because I have a bit of code that works like that and it sort of doesn't work
To be specific, here's the code:
<!DOCTYPE html>
<html>
<head>
<title>MyohTheGod's Website</title>
<link rel="icon" type="image/x-icon" href="/supercorn.gif" defer>
</link>
<link id="css" href="/css/dark.css" rel="stylesheet" type="text/css">
</link>
<script src="/js/particles.js" defer></script>
<script src="/js/header.js"></script>
<script src="/js/theme.js"></script>
<script>window.alert("Welcome to the Home of MyohTheGod. You can play games, check out our web proxies, and more. Also, please do check out the About page. Press OK to continue...");</script>
</head>
<body>
-snip-
</body>
<script id="foot" src="/js/footer.js"></script>
</html>
<script>
-snip-
</script>
var css = document.getElementById("css");
var foot = document.getElementById("foot");
function toggleDLmode(m) {
-snip-
if (dlmodebool) {
css.href = "/css/dark.css"
foot.src="/js/dark-footer.js"
} else {
css.href = "/css/index.css"
foot.src="/js/footer.js"
}
}
-snip-
It is working, do you inspect it? It does changed, but maybe you're thinking, "hm why this /js/anotherfile.js is not downloaded?". Well because of the script tag is already rendered and already downloaded, so you can't do that. What you can do though add NEW script tag.
Maybe this will help How to dynamically change the script src?. This links would explain more why your code "does not work".
There certainly is. You can use document.scripts which returns an collection that you can iterate through like an array. You can change the code using the innerHTML property very much like a normal element. See here https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection
Edited to add: If you've got a html page with multiple script tags, the document.script collection has each script in the order they appear. The code below will log out the source (src tag) or the actual javascript for each script element.
You can also 'write' javascript by setting the innerHTML property.
IMHO it's a bit of a solution that's looking for a problem but at least it gives you access to the number of scripts you have.
[...document.scripts].forEach(script => {
if (script.src != '') {
console.log("Script source:" + script.src);
} else {
console.log(script.innerHTML);
}
});

Create HTML doc like Bootstrap with Prism

I am facing a problem about how to create HTML code examples with Prism, either with pure JS or VueJS.
I need to get something like Bootstrap documentation, with several lines of HTML code displayed, indented, and highlighted.
It works when I put the HTML code directly between the pre/code tags, replacing the < with <.
But I want something more automatic, in which you write a line of code, for example to create a button, and under it, you have the code displayed.
So I am looking for a way to copy this line of code between the pre/code tags.
The problem is that either through the data objects of Vuejs (putting it as a string), or with the appendChild or innerHTML DOM methods, it doesn't works.
With VueJS I get a highlighted line of code but I can't have a multi-line example.
With appendChild and innerHTML, is displayed only the content of the element, for example the text between the button or div tags.
What I need is a way to display all the code, from < of the first tag to > of the last one.
How can I achieve this? Is it possible or is HTML impossible to easily display in the browser?
Here is the easy JS example I am working on.
If you uncomment the line between code tags, you will have the working example, the result I want to get from a more automatic way, just writing once the line of code, and then copying it.
Thanks
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>About</title>
</head>
<body>
<div id="gg" class="div" data-modifiers='["div--small", "div--big"]'>About</div>
<pre>
<code id="hh">
<!-- <div class="div" data-modifiers='["div--small", "div--big"]'>About</div>-->
</code>
</pre>
<script>
const example = document.getElementById('gg');
const toDisplay = document.getElementById('hh');
// toDisplay.appendChild(example);
hh.innerHTML = gg.innerHTML;
</script>
</body>
</html>
I finally found the solution using only pure JS (no framework).
I share the solution if one day someone needs it.
You can add Prism to get a highlighted displayed code.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>About</title>
</head>
<body>
<div id="gg" class="div" data-modifiers='["div--small", "div--big"]'>
<p>fff</p>
About
</div>
<pre>
<code id="hh" class="language-html">
</code>
</pre>
<script>
const example = document.getElementById('gg').outerHTML;
const toDisplay = document.getElementById('hh');
const regex = /</gi;
renamed = example.replace(regex , '<');
hh.innerHTML = renamed;
</script>
</body>
</html>

Swapping text for an image in Javascript

I'm looking for a way that I can search an entire HTML document for a specific word and then swap each instance of that word with an image.
The problem I have is that I don't know what content is there because it is a dynamic page where the content is edited elsewhere and the site just pulls it in so referencing classes and ids is difficult.
I created a simple example with text that could resemble the content but the problem I have is my script will replace the whole document (I believe because of .html?) and I just want it to replace that specific piece of text.
<p>hi</p>
<p>j</p>
var x = $('body:contains("hi")');
x.html('<img src="/Content/by_car.jpg" />');
Could someone point me in the right direction?
Thanks in advance
You need to replace the original html like so x.html(x.html().replace('hi', '<img src="/Content/by_car.jpg" />'));
Also, this will be bad if, for example you will have <p class="hiblo">hi</p>. In this canse it will replace hi in hiblo and hi inside p tag thus ruining your markup.
Generally you can use some kind of regex but it's still not recommended to parse html with regex.
Here is working code.
This code also makes sure that script and style tags don't get replaced otherwise page logic will be broken. So it is taken care of as well.
<html>
<head>
<script type="text/javascript" src="jquery-1.11.3.min.js" > </script>
<style></style>
</head>
<body>
<h1>hi</h1>
<div>hi</div>
<input type="button" onclick="return replaceWithImage()" value="replace with image"/>
<script type="text/javascript">
function replaceWithImage() {
var x = $('body').find(':contains("hi")');
x.each(function(){
if($(this).prop('tagName') != 'SCRIPT' && $(this).prop('tagName') != 'STYLE')
$(this).replaceWith('<img src="/Content/by_car.jpg" />');
});
return false;
}
</script>
</body>
</html>

Polymer core-label and core-checkbox dynamic

I'm trying to generate a list of core-label elements with javascript.
In the documentation(https://www.polymer-project.org/docs/elements/core-elements.html#core-label) it is written, that I may add the attribute for in an input-element inside the core-label to connect them.
If I code it static like this, it is possible:
<core-label>
<core-image></core-image>
<paper-checkbox for></paper-checkbox>
<span>Text</span>
</core-label>
But if i try to add those elements dynamic inside a script, those elements are not connected...
var catLayout = document.createElement("core-label");
var img = document.createElement("core-image");
var chk = document.createElement("paper-checkbox");
chk.setAttribute("for","");
var label = document.createElement("span");
var labelcontent = document.createTextNode("text");
label.appendChild(labelcontent);
catLayout.appendChild(img);
catLayout.appendChild(chk);
catLayout.appendChild(label);
May anyone tell me, whats wrong?
What you're doing should work. I wonder if you're running into a timing issue due to the way you're script is being executed within the larger context of your application. But here's a functionally equivalent snippet that does the job:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="//www.polymer-project.org/webcomponents.js"></script>
<link rel="import" href="//www.polymer-project.org/components/core-label/core-label.html">
<link rel="import" href="//www.polymer-project.org/components/paper-checkbox/paper-checkbox.html">
<div>
<core-label>
<paper-checkbox for></paper-checkbox>
<span>Created via Markup</span>
</core-label>
</div>
<div id="container"></div>
<script>
var coreLabel = document.createElement('core-label');
var paperCheckbox = document.createElement('paper-checkbox');
paperCheckbox.setAttribute('for', '');
var text = document.createElement('span');
text.textContent = 'Created via JavaScript';
coreLabel.appendChild(paperCheckbox);
coreLabel.appendChild(text);
document.querySelector('#container').appendChild(coreLabel);
</script>
</body>
</html>
That being said, I'm curious as to why you need to create these elements via JavaScript. I personally find Polymer code much easier to read and maintain when as much as possible is handled via the DOM using Polymer's <template> logic. For instance, if you're resorting to JavaScript element creation because you want to include these elements conditionally, wrapping <template if="{{your_condition}}"> around that section of your DOM could take care of that for you. Similarly, if you're doing this from JavaScript because you want to repeat the logic multiple times for each element in an array, <template repeat="{{item in your_array}}"> can handle that for you. The data-binding section of the docs is great if you haven't seen it.

Javascript to rotate between pages within ONE HTML page

I would like some help displaying contents (to different pages) within one HTML page using JavaScript.
This is a sample of what I have found so far: http://www.swan10.nl/stuff/test.htm however instead of displaying "FAQ question #blabla" in the box every time a link is clicked, I would like to display words and images like a normal content. Is there a way to do this?
I tried removing the CreateDiv function and replacing it with HTML codes but it doesn't work.
Thank you in advance :)
Umm, well you would need to use AJAX to pull the data into the page and display it in whatever method you choose. If you want to use a framework look into JQuery. It has nice AJAX functions. Otherwise read HERE
After re-reading your post I think you might just want to choose which div is displayed on a form at one time. This you can achieve by placing all of your divs in the same container. Then toggle their display css property.
Using jQuery it's as simple as
$('#divname').load('/path/to/file.html');
Note that the result should probably not include <html> and <head> tags (although you don't seem like you care about well formed HTML code).
I should probably also mention that you shouldn't make the client load content for you, that's what server side code is for.
Personally I would use the innerHTML property on one of your elements. It will allow you to add markup to that element. Check it out here: http://www.w3schools.com/jsref/prop_html_innerhtml.asp
<html>
<head>
<title>Multiple DIV</title>
<style type="text/css">
DIV#db {
border : 1px solid blue;
width : 400px;
height : 400px;
}
</style>
<script type="text/javascript">
var Content = new Array();
Content[0] = '<i>test1</i>';
Content[1] = '<b>test2</b><br><img src =http://www.w3schools.com/images/w3schoolslogo.gif>';
Content[2] = '<u>test3</u>';
Content[3] = '<s>test4</s>';
function Toggle(IDS) {
document.getElementById('db').innerHTML = Content[IDS];
}
</script>
</head>
<body onLoad="Toggle(0,10)">
FAQ #1
FAQ #2
FAQ #3
FAQ #4
<p />
<div id="db"></div>
</body>
</html>
I updated it to work all javascripty with the innerHTML

Categories