How to support latex in GitHub-pages? - jekyll

I use jekyll to write post and show it in GitHub-pages. My source file is written with markdown.
How can I insert formula into the markdown file?
I don't want to save the formula into an image and load the image in markdown file. I actually want to write latex formula in markdown file directly.

Since resources online have changed regarding this question, here's an update on supporting LateX with GitHub Pages.
Note that the closest to Latex rendering without exporting as images and natively supporting it on your Jekyll site would be to use MathJax.
MathJax is actually recommended in Jekyllrb docs for math support, with Kramdown, it also converts it from LaTeX to PNG, more details on it here at the Kramdown documentation
Option 1: Write your equation in MathURL and embed it.
You could write the equation with MathURL, then generate a url that permanently points to the equation, and display this in an <iframe> tag. However, this will stop working if MathURL goes offline.
Option 2: Implement jsMath
jsMath will allow almost LateX like syntax and will be supported in your blog if you have set it up correctly, there is extensive documentation on this.
Option 3: Mathjax (by far the easiest in my opinion)
Many sites have mentioned that Mathjax is considered a successor of jsMath, and is much easier to implement with Jekyll. MathJax is also used by mathematics.stackexchange.com too!
Step 1: Have your site load the script in sites where you want to display math. (usually done in the header)
Optional: Check your markdown parser in _config.yml. redcarpet or kramdown is suggested in this example. Certain parsers like discount will interfere with the syntax but I have a solution below.
Step 2: Write your equations.
Quoting this tutorial by Gaston Sanchez:
MathJax does not have the exactly same behavior as LaTeX. By default,
the tex2jax preprocessor defines the LaTeX math delimiters, which are
\(...\) for in-line math, and \[...\] for displayed equations. It
also defines the TeX delimiters $$...$$ for displayed equations, but
it does not define $...$ as in-line math delimiters.
Read the documentation on the syntax for more details.
Note: Using the raw liquid tag to ensure Markdown parsers do not interfere with MathJax syntax.
While you could escape backslashes (e.g. \\[ \frac{1}{n^{2}} \\])to
ensure they are parsed properly, as described by Chistopher Poole's
tutorial, this is not always intuitive and looks complicated. A
simpler solution would be to use the raw liquid tag to ensure the
text is ignored by the Markdown processor and directly output as a
static html. This is done with {% raw %}and also {% endraw %}
Here is a code sample:
{% raw %}
$$a^2 + b^2 = c^2$$ --> note that all equations between these tags will not need escaping!
{% endraw %}
Lastly also ensure that the fonts support displaying LateX as some have issues like font size being too small. Alternatively here are some additional methods like Google Charts and MathML discussed in the latex StackExchange sister site.

If you used Jekyll in your GitHub pages, you can add
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
inlineMath: [['$','$']]
}
});
</script>
<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>
in the file _includes/head.html, and then your GitHub Pages site will support MathJax

The easiest way to do this right now is to use the KaTeX auto-render extension.
Simply drop the following into your <head>:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex#0.10.2/dist/katex.min.css" integrity="sha384-yFRtMMDnQtDRO8rLpMIKrtPCD5jdktao2TV19YiZYWMDkUR5GQZR/NOVTdquEx1j" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex#0.10.2/dist/katex.min.js" integrity="sha384-9Nhn55MVVN0/4OFx7EE5kpFBPsEMZxKTCnA+4fqDmg12eCTqGi6+BB2LjY8brQxJ" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex#0.10.2/dist/contrib/auto-render.min.js" integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
Note that this assumes the following delimiters appear in your HTML:
$$\LaTeX code$$ (for display)
\\[\LaTeX code\\] (also for display)
\\(\LaTeX code\\) (for inline)
Note, if using Jekyll, you will need to have the following in your _config.yml:
markdown: kramdown
kramdown:
math_engine: katex
WARNING: Do not use math_engine: mathjax. It will break this by automatically removing the LaTeX delimiters.

Unfortunately most answers here are outdated nowadays. Github renders your markdown files using kramdown . Annoyingly kramdown defines math content differently from other markdown variants. In kramdown inline math is written using $$ as delimiter like text $$ E = mc^2 $$ text. Display math is also written using $$ delimiter, but it must be separated from the text by a blank line
text
$$\begin{aligned}
E = mc^2
\end{aligned}$$
text
Kramdown will render the inline math as \( E = mc^2 \) and the display math as
\[\begin{aligned}
E = mc^2
\end{aligned}\]
in your output HTML. These are also the delimiters used by mathjax as default. Therefore to configure MathJax 3 for github pages it is enough to add
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-mml-chtml.js"></script>
to the file _includes/head-custom.html. You don't need to create or modify the _config.yml file.
I recommend you to use MathJax 3 over KaTeX, because MathJax 3 is not much slower anymore than KaTeX (see https://www.intmath.com/cg5/katex-mathjax-comparison.php) and supports more features (E.g. KaTex cannot handle \label and \eqref (see https://github.com/KaTeX/KaTeX/issues/2003))
If you still want to use https://katex.org/docs/autorender.html you must add
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex#0.15.6/dist/katex.min.css" integrity="sha384-ZPe7yZ91iWxYumsBEOn7ieg8q/o+qh/hQpSaPow8T6BwALcXSCS6C6fSRPIAnTQs" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex#0.15.6/dist/katex.min.js" integrity="sha384-ljao5I1l+8KYFXG7LNEA7DyaFvuvSCmedUf6Y6JI7LJqiu8q5dEivP2nDdFH31V4" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex#0.15.6/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"
onload="renderMathInElement(document.body);"></script>
to the file _includes/head-custom.html. You don't need to create or modify the _config.yml file.
Note: I tried to use github flavored markdown renderer instead of the default renderer for github pages by setting markdown: GFM in the the _config.yml file. This would give you additional features like autolinks ( see https://github.community/t/github-pages-autolinks-fail/129713/4 ) and the more common $ delimiter for inline math and $$ delimiter for display math (https://github.blog/2022-05-19-math-support-in-markdown/) as it is supported by https://pandoc.org/. However the GFM markdown renderer from github has still many, many problems with math section making it unusable (https://nschloe.github.io/2022/05/20/math-on-github.html).

A while ago I created xhub, a browser extension that allows you to use math in github pages.
Cons:
You have to install the extension.
Pros:
No need to set up any workflow.
Just edit your markdown as usual and use
Display math:
```math
e^{i\pi} + 1 = 0
```
and inline math $`a^2 + b^2 = c^2`$.
(Syntax just like on GitLab.)
Works well on light and dark background.
You can even copy-and-paste the math!
Perhaps worth checking out.

I would like this to be a comment on daviewales answer but I do not have enough reputation unfortunately. My understanding of that answer is to copy the 3 lines of code into the file <your_repo>.github.io\_site\<postname>\index.html. However, that file seems to get updated each time the corresponding <postname>.md is edited. Is there a more elegant way to always get those lines of code automatically added to the html file, without having to manually edit it every time I want to check an equation?
EDIT:
I think this is one solution to the above problem:
What ended up working for me was based off of PeaShooter's response. I made a folder _includes within my _posts folder, and then populated it with a file head.html containing the code from PeaShooter's answer. Then, in the top line of the post below the YAML front matter (i.e. below the second --- line) I put the code {% include_relative _includes/head.html %}
Note that it was important to make the _includes folder not in base folder <your_repo>.github.io, but within the _posts folder. While placing _includes in the base folder did automatically generate the equation, it ruined the formatting for the rest of the website.

The best way right now IMO is to use the MathJax backend (which is part of kramdown, i.e. available on GitHub Pages) and then use KaTeX on the frontend for rendering. KaTeX is more lightweight and faster than MathJax, which makes it a better fit for a blog theme.
I'm using this technique with great success for my Jekyll theme Hydejack. Feel free to use it on your own site, by doing the following:
In config.yml, set the math engine to mathjax:
kramdown:
math_engine: mathjax
Add KaTeX to your site and also make sure the following code runs sometime after it has loaded.
const mathBlocks = document.querySelectorAll('script[type^="math/tex"]');
Array.from(mathBlocks).forEach((el) => {
const tex = el.textContent.replace("% <![CDATA[", "").replace("%]]>", "");
el.outerHTML = window.katex.renderToString(tex, {
displayMode: el.type === "math/tex; mode=display",
});
});
The actual code I'm using is slightly more complicated. You can check it out on GitHub.

Some of the answers are a bit complicated or even outdated so here's a recent solution that works well for me. You can solve the problem using layouts.
Create a folder _layouts to the folder from which you publish (for example docs/).
Create default.html. This will be the layout for all your pages. If you have just started your page, you can use this as a template for the default.html file:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{ page.title }}</title>
</head>
<body>
{{ content }}
</body>
</html>
Then add this script before </html>:
<script
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
type="text/javascript">
</script>
I had the problem that I was using minima theme. So if I applied the change above I lost my theme in my posts. I went to the github repo and copied whatever they had in default.html and added the script above before </html> and it worked!
I found out the answer here.

Related

Vim unexpectedly sources javascript indent filetype plugin on editing html files

TL;DR: vim seems to be sourcing both indent/javascript.vim and indent/html.vim on editing html files; is this intentional or a bug? How can I make html files only source html.vim?
Recently I found out that vim seems to be using indent filetype plugins for both javascript and html on editing html files, and I've done some testing based on this behaviour on minimal vim configurations.
Here is my one-line .vimrc:
filetype plugin indent on
Inside my .vim directory:
~ % tree .vim
.vim
└── indent
├── html.vim
└── javascript.vim
1 directory, 2 files
Where:
~ % cat .vim/indent/javascript.vim
setlocal formatprg=js-beautify
let g:testvar_js="js testvar"
let g:testvar="testvar defined in javascript.vim"
and
~ % cat .vim/indent/html.vim
setlocal formatprg=html-beautify
let g:testvar_html="html testvar"
let g:testvar="testvar defined in html.vim"
Then I open up a new, empty vim buffer with vim foo.html, and tested with some commands:
:set filetype?
filetype=html
:set formatprg?
formatprg=js-beautify
:echo g:testvar
testvar defined in javascript.vim
:echo g:testvar_html
html testvar
:echo g:testvar_js
js testvar
As if vim sources both indent filetype plugins, with indent/html.vim first and then indent/javascript.vim.
Therefore, my questions are:
Did I make any silly mistakes?
If no, then is this an intentional design, a bug, or is that vim has nothing to do with this at all?
Is there a way to make vim only source on html.vim when editing html files?
Some additional information that might be helpful:
I'm on vim 8.2, macOS arm64, using Terminal.app
Neovim exhibits the same behaviour; actually that's where I first note it
This behaviour does not occur for ftplugin/, only indent/
javascript files are not affected by indent/html.vim: variables defined in indent/html.vim are all undefined in a javascript buffer
formatprg of html files is always js-beautify on open, regardless of if there are any javascript code pieces or <script> tags inside that html file
An indent/css.vim will not be involved at all when editing html - I've tested
js-beautify and html-beautify are two separate executables (repository is here)
bin % ls -n js-beautify
lrwxr-xr-x 1 501 80 53 Apr 19 17:59 js-beautify -> ../lib/node_modules/js-beautify/js/bin/js-beautify.js
bin % ls -n html-beautify
lrwxr-xr-x 1 501 80 55 Apr 19 17:59 html-beautify -> ../lib/node_modules/js-beautify/js/bin/html-beautify.js
If you want me to do some additional tests or need more information, just shout.
Many thanks
Here is a perfectly valid HTML sample:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Sample</title>
<script>
console.log('Hello, World!');
</script>
<style>
body {
background: orange;
}
</style>
</head>
<body>
<h1>Sample</h1>
</body>
</html>
You will notice it has a tiny bit of embedded JavaScript in it, which is a good enough reason for $VIMRUNTIME/indent/html.vim to source $VIMRUNTIME/indent/javascript.vim. After all, the javascript indent script is supposed to know how to indent JavaScript, so why not use it in a html buffer that can contain embedded JavaScript?
FWIW, here is the snippet responsible for that behaviour:
if !exists('*GetJavascriptIndent')
runtime! indent/javascript.vim
endif
Note that the maintainers of $VIMRUNTIME/indent/html.vim chose the external route for javascript and the internal one for css. Maybe because $VIMRUNTIME/indent/css.vim didn't fit the bill? I don't know and, frankly, I don't think it matters.
Now, let's go through your mistakes…
Filetype-specific scripts (indent, syntax, ftplugins) are sourced in this order:
~/.vim/indent/<filetype>.vim,
$VIMRUNTIME/indent/<filetype>.vim
~/.vim/after/indent/<filetype>.vim
If you are not very careful, stuff you put in an earlier script might be overwritten when a later script is sourced. For that reason, it makes a lot more sense to put your own stuff in scripts under after/.
The following lines have nothing to do in indent scripts:
setlocal formatprg=js-beautify
setlocal formatprg=html-beautify
They are supposed to be in ftplugins:
" after/ftplugin/javascript.vim
setlocal formatprg=js-beautify
" after/ftplugin/html.vim
setlocal formatprg=html-beautify
So…
Did I make any silly mistakes?
Yes, see above.
If no, then is this an intentional design, a bug, or is that vim has nothing to do with this at all?
Well yes, this is an intentional design that works pretty well. It only caused problems because you misused it.
Is there a way to make vim only source on html.vim when editing html files?
indent/html.vim? Yes, it certainly is possible but why would you want to do that?
ftplugin/html.vim? It already works the way you want and it is the right place for the things you mistakenly put in indent/html.vim to begin with.
--- EDIT ---
Just curious, indent/ files are supposed to set indentation options right, then why shouldn't I set the indentation program there?
Filetype-specific scripts are typically sourced once, when a file of the corresponding filetype is loaded into a buffer. Because it is relatively common to have languages embedded in other languages (JavaScript in HTML) or languages that are supersets of other languages (C++ vs C), Vim makes it possible to source other filetype-specific scripts. That's pretty much a concrete example of code reuse and that's generally considered a good thing.
Indent scripts can source other indent scripts, syntax scripts can source other syntax scripts, and ftplugins can source other ftplugins.
So Vim gives us a useful low-level mechanism but it is up to us to decide what to put where, and that always depends on the context.
In the case of HTML, it makes sense to use the existing JavaScript indent stuff, so $VIMRUNTIME/indent/html.vim sources $VIMRUNTIME/indent/javascript.vim early on and then proceeds with setting HTML-specific stuff. The end result is a html indent script that also supports embedded JavaScript. The html syntax script uses a similar mechanism in order to highlight embedded JavaScript. In some simple cases, you can even have one ftplugin sourcing another ftplugin but $VIMRUNTIME/ftplugin/html.vim doesn't.
But it doesn't always makes sense: options may be overwritten, mappings may be overwritten or defined in contexts where they don't make sense, etc. In this specific case, what external tool to use for formatting is highly context-sensitive: you can't really expect js-beautify to format HTML properly or html-beautify to format JavaScript properly so formatprg must be set separately for the javascript and html filetypes.
ANd this is where your first mistake kicks in.
Here is once again the snippet that sources $VIMRUNTIME/indent/javascript.vim from $VIMRUNTIME/indent/html.vim:
if !exists('*GetJavascriptIndent')
runtime! indent/javascript.vim
endif
:help :runtime is a smart alternative to :help :source that looks for files in :help 'runtimepath'. Because your ~/.vim/indent/javascript.vim is in your runtimepath, it will be sourced. Because there is a !, every matching file is going to be sourced. Because it comes first in runtimepath, it might be overwritten by later scripts.
In your case, $VIMRUNTIME/indent/html.vim automatically sources your ~/.vim/indent/javascript.vim, which contains stuff that shouldn't be set in a html buffer.
The after directory allows you to have the last word on what is set for a given filetype because built-in scripts rarely, if ever, do runtime! after/indent/<filetype>.vim
That explains why it is a bad idea to carelessly put your filetype-specific stuff in ~/.vim/{ftplugin,indent,syntax}/ and why you should put it in ~/.vim/after/{ftplugin,indent,syntax}/ instead.

How to create new entities in Jekyll + Markdown

I have a bunch of Markdown files. In them, I want to be able to use custom bullets and other images; these are implemented as images (with alt-text, but they're a lot prettier as images). The Markdown to create one of those images looks like this:
*![✨](https://s.w.org/images/core/emoji/2.2.1/svg/2728.svg)*
(Yes, that's rendered inside <em> </em> - that's to simplify the CSS, since I can't put a class on the img tag easily.)
Is there a way to tell the parser that the single character ✨ should be rendered as the entire <img> tag?
The site is hosted on GitHub Pages, so answers need to restrict themselves to GitHub Flavored Markdown. If it can't easily be done, I could make a pre-commit hook or something and run a local parser, but it would be far easier to have it work automatically.
You can put the emojis in includes and then reference them from your posts. That is compatible with Github Pages as it doesn't require plugins.
In your post put:
{% include emoji.html %}
That will load the contents of _includes/emoji.html:
✨
You can pass parameters to it to load different images depending on the image you want to load, e.g.: {% include emoji.html image="stars" %}
Another option is to create custom liquid tags that load them.
...since I can't put a class on the img tag easily.
You can if you use kramdown - it has a feature, which allows assigning attributes to the block level elements. For example:
![img]({{ 'img.png' | relative_url }}){: .center }
will become
<img src="...img.png" alt="img" class="center">

Stop '---' being transformed to '<hr />'

I'm inserting remark.js slides (as MD files) into a jekyll site (hosted on github, and pre-processing done there).
Since remark.js uses three dashes to indicate a next slide, it's important that these three dashes do not get transformed into a new line '<hr />'.
Is there a way to turn off jekyll preprocessing within an MD file? Or, change the behavior so that --- are not transformed into <hr /> ?
I believe you would need to enter a backslash before the three hyphens, according to this document linked to from Jekyll's website.
Markdown allows you to use backslash escapes to generate literal characters which would otherwise have special meaning in Markdown’s formatting syntax.
But depending on the markdown processor you are using with Jekyll, the escape character could be something other than a backslash, or you might need to escape each hyphen.
This might be an old post, but recently I hit the same issue:
I couldn't escape --- in markdown such that remarkjs can render them as individual slides. In Jekyll 4.2.2, the --- was converted into </hr> and this was braking remarkjs.
My solution was to write my content for slides into an .md file and put it under _includes/presentations. I didn't add any --- at the beginning of this file so it will not be picked-up by Kramdown for processing. Then I added a regular .md file in _posts, to this file I added the previous one as an include between <pre> tags.
Content of the post file is:
---
layout: presentation
title: TDD Workshop Presentation
permalink: /tdd-workshop-presentation/
---
<pre>{% include presentations/tdd-workshop-1.md %}</pre>
Content of presentations/tdd-workshop-1.md
# TDD
## Test Driven Development Workshop
---
# Agenda
1. Introduction
2. Deep-dive
3. ...
Please mind the new line at the beginning of this file, as that's necessary for the first tag to be rendered properly.
I hope that this helps.

Split html source into multiple files

Does HTML support splitting source over multiple files? I'm looking for some equivalent of C++'s #include; or maybe something like C#'s partial; an element that could take source path and inject the file contents at that place.
Apologies if this has been asked before. Google and SO searches didn't return much. I'm not a web guy, but the only solution I found was using an iframe, which many people do not like for various reasons.
It is just that my html source is becoming huge and I want to manage it by splitting into multiple files.
You can't, at least not in flat-HTML. What you can do is using Javascript to load and place the snippets. iframes are also non-ideal because contrary to what happens with directives like #include and partial, those snippets will never be compiled in one single page.
However, I think it's important here to understand how your pages will be served. Is this a static website? Because in this case I would write a simple script in your language of choice to compile the page. Let's say that you have a base like this:
<html>
<head>
<!-- ... -->
</head>
<body>
{{ parts/navigation.html }}
<!-- ... -->
</body>
</html>
You could write a script that runs through this file line by line and loads the content into a variable named, for example, compiled_html. When it finds {{ file }} it opens file, reads its content and append it to compiled_html. When it gets to the end, it writes the content of the variable into a HTML file. How you would implement it depends on the languages you know. I'm sure that it's pretty straightforward to do it in C#.
This way you'll be able to split the source of your HTML pages into multiple files (and reuse some parts if you need them), but you'll still end up with fully functional single files.
It is easily possible, if you are running PHP:
The PHP Language has the "include" command built in.
Therefore you can have your "index.php" (note you have to change the suffix, for the PHP parser to kick-in) and simply use following syntax.
<html>
<head>
[...] (header content you want to set or use)
</head>
<body>
<?php
include "relative/path/to/your/firstfile.html";
include "relative/path/to/your/secondfile.html";
include "relative/path/to/your/evenwithothersuffix/thirdfile.php";
include "relative/path/to/your/fourth/file/in/another/folder.html";
?>
[...] (other source code you whish to use in the HTML body part)
</body>
</html>
Basically making you main index.php file a container-file and the included html files the components, which you like to maintain seperately.
For further reading I recommend the PHP Manual and the W3Schools Include Page.
not possible with static html.
in general, this problem (lazy-fetching of content) is solved with a template processor.
two options:
template processor runs on the server side
any language
static website generators, server side rendering
template processor runs on the client side
javascript
web frameworks

Use kramdown with pygments in Jekyll

I want to use kramdown (with features such as fenced code blocks, inline attribute lists, header IDs) together with pygments for syntax highlighting (e.g. for LaTeX support, which is not available with CodeRay used by kramdown). Jekyll supports both kramdown and pygments, but apparently not the two together (unless I use Liquid tags which I would prefer not to).
I've also found some plugin snippets of how to make kramdown fenced code blocks spit pygments highlighted code, but unfortunately I don't know how to make that work.
I tried dumping all of the code from that site on some _plugins/krampygs.rb file, but then jekyll build complains about:
Generating... error: undefined method `matches'
If I supply some trivial matches and output_ext as instructed by Jekyll plugin docs, but then I don't know how to select this new converter for my .md files. Adding something like
markdown: MarkdownConverter
on my _config.yml only complains that this is not a valid option.
So, well, I restate my question: How can I use kramdown with pygments in Jekyll?
Solution
With the help of Matthias (below), I was able to prepare this Kramdown+Pygments plugin for Jekyll 1.x.
Author of "that site" here.
It depends on the Jekyll version. For the version when the post was written, that was enough. At least Jekyll 1.x requires that matches is defined in the MarkdownConverter, like so:
def matches(ext)
ext =~ /^\.md$/i
end
Another problem that appears with Jekyll 1.x is that every custom Markdown converter is ignored. I worked around this by by stating the output extension explicitly
def output_ext(ext)
".html"
end
and tell Jekyll that to look for a bogus Markdown extension by setting
markdown_ext: foo
in _config.yml.
I have updated the plugin created by Juan, to be compatible with Jekyll 2.x, along with some other improvements.
It can be found here: https://github.com/mvdbos/kramdown-with-pygments.git