/adoc-math

Use MathJax (Latex or AsciiMath) in your AsciiDoc projects πŸ€ŸπŸš€

Primary LanguagePython

adoc-math

πŸ“ Example

πŸ“ Installation

adoc-math has zero depependencies! So it’s fine to install it globally[1] πŸ˜›

pip3 install --user --upgrade adoc-math
adoc-math-setup # will call `npm i -g mathjax@3` and `npm link`

πŸ“ Overview

πŸ” Background

I think of AsciiDoc as a markup syntax somewhere between Markdown and LaTeX. It originated with a Python implementation, but afaik that isn’t actively developed, and the reference implementation is Asciidoctor in Ruby.

AsciiDoc allows you to write a document and then output it in:

and many other formats! There is even an Asciidoctor.js version (an automated translation of the Ruby code to JavaScript).

πŸ” LaTeX

Putting LaTeX equations in other places than a TeX document is not so easy. There are two main libraries for this:

  • MathJax

    • It uses native browser fonts and a lot of Css to replicate LaTeX in the browser.

    • It also has an svg output option!

  • KaTeX

    • Similar to MathJax, built by Khan Academy.

    • Does not have svg output.

πŸ” STEM

STEM stands for Science, Technology, Engineering, Mathematics, basicaly LaTeX. There are two sections in the AsciiDoc documentation on STEM:

The TLDR is:

πŸ” adoc-math

That’s where adoc-math comes in! I decided for:

  • a Python package that searches for naturally-looking latex cells (e.g. $a+b$), calls MathJax to create an svg, and replaces the cells with an image of the svg

I couldn’t use KaTeX because only MathJax has an Svg output (see KaTeX/KaTeX#375).

Unfortunately, MathJax 3 doesn’t come with a Node CLI package like MathJax 2. So I implemented a wrapper over the library.

πŸ” Usage

Inline cells:

$x + y$ [...options]

Block cells:

$$ [...options]
x + y
$$

For more examples, see the Example.

πŸ“ FAQ

Why isn’t adoc-math written in Ruby?

I don’t speak Ruby 😞 If you would like to translate this library to Ruby, or at least an AsciiDoc macro that can get replaced by an image, so we cant get rid of the extra metacompilation step, I’d be more than happy to help!

Why aren’t inline cells avaiable "in line", such as "Let $x$ be a integer."?

This decision was chosen very early during development. It makes the parsing logic easier, and reduces the change that a paragraph containing two dollar signs will get replaced by LaTeX. In theory, it would be possible to add this; however, the output will still have at least one linebreak, since we want to comment out the source math. We would probably be better off just making an Asciidoc macro (stem[], m[], or something similar), but we need a Ruby speaker!

What are ex units?

An ex unit is equal to the font size (height) of the lowercase x character. So it’s roughly one half of a line? It’s used in Mathjax’s svgs (as the width, height and vertical-align) and in adoc-math to adjust the vertical-align.

What about Windows?

I tried to be conscious of non-Posix platforms, but haven’t tested in on Windows. Any behavioral discrepancies would be considered valid issues.

Can I reference a cell, or add a caption to a block cell?

Yes! Check out the Example.

It’s annoying having to uncomment the source math to edit it.

You can use a pre-post pattern. pre.adoc will be your source code, and post.adoc will be the output of adoc-math / input to asciidoctor(-pdf)?. Run cpy pre.adoc post.adoc before every invocation to adoc-math.

How come inline cells become part of the sentence when they are on a separate line?

In AsciiDoc, you need to separate two blocks with at least one empty line. πŸ™‚

Does adoc-math work with an Html output?

This first version is geared towards Pdf output. Happy to add more powerful support for Html outputs in the future (e.g., just use the native stem:[] macro for Html, so we can use basic MathJax with browser fonts and Css (instead of svgs)).

Can I use a different font?

Can I make my math thinner/thicker?

The created svgs have a property called stroke-width that can adjust this. Unfortunately, it is currently set to 0, so it is not possible to make it thinner. In theory it should be possible to make it thicker by increasing that value. svg_transforming.py would be the place for that; or create an issue and I’ll add it.

πŸ“ Debugging

I get a MODULE_NOT_FOUND error.

MathJax probably cannot be found. Try running adoc-math-setup.

My AsciiMath fractions are too large!

It seems that AsciiMath interprets fractions in displaystyle rather than textstyle (\dfrac{}{} rather than \tfrac{}{} or even \frac{}{}, see StackExchange).

I haven’t found a good solution to this yet. If you have any ideas, please let me know! Note that if you have a singleton fraction ($a/b$ amath) you can scale it down with $a/b$ amath, scale = 60% (or just use tex).

Math in bullet points causes my text not to be aligned with the bullet point.

readme faq unaligned bullet point

Try playing around with the positioning and vertical align offset. In this example, just adding dont_position to this cell’s attributes fixes the issue:

readme faq aligned bullet point

Adding math in a 4th-order bullet point causes weird rendering.

In AsciiDoc, literal blocks can be delimited (created) with ---- or ****. So if you need to have something like:

* one
** two
*** three
****
$1 + 1 = 4$

AsciiDoc will recognize the **** as an opening of a literal block.

The solution to this is to add something after the ****. This uses the builtin {empty}:

* one
** two
*** three
**** {empty}
$1 + 1 = 4$

1. Theoretically, the only time this could cause issues is if you have another package which has the name adoc-math (it obviously has to have a different PyPI name, because adoc-math is already taken πŸ˜›. But this is not very likely.. )