GithubHelp home page GithubHelp logo

martenlienen / pelican-katex Goto Github PK

View Code? Open in Web Editor NEW
18.0 18.0 5.0 434 KB

LaTeX pre-rendering for pelican

License: GNU General Public License v3.0

JavaScript 96.33% Python 3.67%
katex math pelican

pelican-katex's Introduction

LaTeX Pre-rendering for Pelican

pelican-katex integrates LaTeX rendering directly into the pelican generation process and eliminates the delay in displaying math you usually experience on the web. It does so by hooking itself into docutils' reStructuredText parser as well as the markdown package and processing the formulas with KaTeX. The generated HTML pages only contain the finished HTML/MathML output. Therefore, you do not need to ship the KaTeX javascript implementation with your website anymore and improve the accessibility as well as the load time of your internet presence.

For a demo visit this blog post. Notice how all the formulas are just there. There is no loading and the website does not even serve the javascript part of KaTeX.

Note, that you still need to include the KaTeX stylesheets with your website, for example

<link rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/katex/dist/katex.min.css"
      crossorigin="anonymous">

Installation

First of all, you need to install nodejs so that pelican-katex can run KaTeX. Then run pip install pelican-katex and add "pelican_katex" to the PlUGINS setting in your configuration file. Finally, remove the katex.js <script> tag from your template and enjoy a lighter website and instant formulas.

Syntax

reStructuredText
~~~~~~~~~~~~~~~~

In rst you write inline math with the usual math role (:math:`f(x)`) or
block math with

.. math::

    \int \textrm{math block}.

# markdown

In markdown you get inline math in between $ signs, like $f(x) = \sqrt{x}$.
Note, that $ only creates a math environment if it is preceded by whitespace
or at the beginning of a block and followed by some non-whitespace character.
This is necessary so that you can still write about the 5$ in your pocket. To
write a dollar sign preceded by whitespace, escape it with a backslash as in
\$10. Block math is triggered with

$$\int \textrm{math block}.$$

Math blocks can have linebreaks but no empty lines.

Configuration

The plugin offers several configuration options that you can set in your pelicanconf.py.

# nodejs binary path or command to run KaTeX with.
# KATEX_NODEJS_BINARY = "node"

# Path to the katex file to use. This project comes with version `0.10` of
# katex but if you want to use a different one you can overwrite the path
# here. To use a katex npm installation, set this to `"katex"`.
# KATEX_PATH = "/path/to/katex.js"

# By default, this plugin will redefine reStructuredText's `math` role and
# directive. However, if you prefer to have leave the docutil's defaults
# alone, you can use this to define a `katex` role for example.
# KATEX_DIRECTIVE = "katex"

# How long to wait for the initial startup of the rendering server. You can
# increasing it but if startup takes longer than one second, something is
# probably seriously broken.
# KATEX_STARTUP_TIMEOUT = 1.0

# Time budget in seconds per call to the rendering engine. 1 second should
# be plenty since most renderings take less than 50ms.
# KATEX_RENDER_TIMEOUT = 1.0

# Define a preamble of LaTeX commands that will be prepended to any rendered
# LaTeX code.
# KATEX_PREAMBLE = None

# Here you can pass a dictionary of default options that you want to run
# KaTeX with. All possible options are listed on KaTeX's options page,
# https://katex.org/docs/options.html.
# KATEX = {
#     # Abort the build instead of coloring broken math in red
#     "throwOnError": True
# }

Preamble

The KATEX_PREAMBLE option allows you to share definitions between all of your math blocks across all files. It takes a string of any LaTeX commands you would like, for example

KATEX_PREAMBLE = r"""
\def\ceil#1{\lceil #1 \rceil}
\def\floor#1{\lfloor #1 \rfloor}
"""

If you have a large preamble, it might be nice to extract it into a .tex file. Note, that pelican will not be aware of changes made to that file in autoreload mode and you will have to restart pelican manually.

from pathlib import Path
KATEX_PREAMBLE = Path("preamble.tex").read_text()

You can also add more definitions per file to the preamble with preamble-blocks that do not produce any output.

reStructuredText
~~~~~~~~~~~~~~~~

.. math::
   :preamble:

   \def\pelican{\textrm{pelican}^2}

This definition will be available in subsequent blocks

.. math::

   \sqrt{\pelican}

or inline :math:`\pelican = 1`.

# markdown

In markdown it is not as easy to define properties of blocks, so we chose to
start a preamble block with an @ such as

$$@
\def\pelican{\textrm{pelican}^2}
$$

which works just the same in blocks

$$\sqrt{\pelican}$$

or inline $\pelican = 1$.

pelican-katex's People

Contributors

martenlienen avatar waltsims avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

pelican-katex's Issues

Node not found

Hey,

when creating files with latest pelican (4.6.0) I get the following error:

[Errno 2] No such file or directory: 'node': 'node'
 |___
 | Traceback (most recent call last):
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/pelican/generators.py", line 622, in generate_context
 |     context_sender=self)
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/pelican/readers.py", line 573, in read_file
 |     content, reader_metadata = reader.read(path)
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/pelican/readers.py", line 337, in read
 |     content = self._md.convert(text)
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/markdown/core.py", line 267, in convert
 |     newRoot = treeprocessor.run(root)
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/markdown/treeprocessors.py", line 370, in run
 |     self.__handleInline(text), child
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/markdown/treeprocessors.py", line 131, in __handleInline
 |     self.inlinePatterns[patternIndex], data, patternIndex, startIndex
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/markdown/treeprocessors.py", line 271, in __applyPattern
 |     node, start, end = pattern.handleMatch(match, data)
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/pelican_katex/markdown.py", line 71, in handleMatch
 |     rendered = render_latex(latex, {"displayMode": display_mode})
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/pelican_katex/rendering.py", line 318, in render_latex
 |     server = RenderServer.get()
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/pelican_katex/rendering.py", line 228, in get
 |     cls.RENDER_SERVER = RenderServer.start()
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/pelican_katex/rendering.py", line 206, in start
 |     process, sock = cls.start_unix_socket(rundir, KATEX_STARTUP_TIMEOUT)
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/site-packages/pelican_katex/rendering.py", line 141, in start_unix_socket
 |     process = Popen(cmd, stdin=PIPE, stdout=PIPE, cwd=rundir)
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/subprocess.py", line 800, in __init__
 |     restore_signals, start_new_session)
 |   File "/Applications/Utilities/miniconda3/envs/pelican/lib/python3.7/subprocess.py", line 1551, in _execute_child
 |     raise child_exception_type(errno_num, err_msg, err_filename)
 | FileNotFoundError: [Errno 2] No such file or directory: 'node': 'node'

Thanks in Advance for your help!

Error on build: permission denied

First of all, thanks for implementing KaTex for markdown too :)

When executing my pelican build script, the following error occurs:

events.js:174
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES: permission denied C:\Users\User\AppData\Local\Temp\pelican_katexrlj4qnm4\katex.sock
    at Server.setupListenHandle [as _listen2] (net.js:1262:19)
    at listenInCluster (net.js:1327:12)
    at Server.listen (net.js:1425:5)
    at Object.<anonymous> (a:\workspace\[PathHiddenOnGithub]\.venv\lib\site-packages\pelican_katex\render-katex.js:34:8)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
Emitted 'error' event at:
    at emitErrorNT (net.js:1306:8)
    at process._tickCallback (internal/process/next_tick.js:63:19)
    at Function.Module.runMain (internal/modules/cjs/loader.js:834:11)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
ERROR: Could not process .\test.md
  | KaTeXError: KaTeX server did not start up after 1.0 seconds. Consider increasing KATEX_STARTUP_TIMEOUT.

It seems that the running process cannot access the temporary path. The directory that should contain katex.sock is just empty. Running the build script with admin rights doesn't help.

  • Windows 10 64 bit
  • Python 3.7.4
  • Nodejs v10.16.3
  • Relevant packages:
    • pelican: 4.2.0
    • pelican-katex: 1.3.0

Math mode font issue

Firstly, thanks for creating this wonderful plugin! Let me describe the problem in the following.

  • pelican: 4.8.0
  • pelican-katex: 1.6.1

Math model font issue, example:
Screenshot 2023-05-10 at 6 33 43 PM

In math mode (in-line or block), I was expecting the notations to be italic, instead all of them were upright. The font didn't look like Computer Modern either. In addition, the command \cal didn't seem to be working. In the example, {\cal D} was supposed to be a cursive D. I was expecting something like:
_f(z_0)_=_frac_

I think this is a simple font setting issue. Somehow the out-of-the-box setting didn't work. Is there a way to fix this? Thanks!

Missing space before inline math

I have a simple pelican page, whose source is

Title: Katex test
Date 2020-02-03

This is a math test $E=mc^2$. Are spaces being properly formatted? 
Is there a space before the math? What about for this  $E=mc^2$?

Rendered at https://abdullahkhalid.com/katex-test/

What happens: For the first equation there is only one space before the $ sign, and this space is eaten up in the rendered version. For the second equation, I have inserted a additional space before the $ sign, which then results in a space before the inline math in the rendered result.
Screenshot_2020-02-03_00-46-48

Expected result: The space before inline math should not be eaten up.

Doesn't work in block-level HTML tags in markdown

I'm using pelican-katex for my blog, where I write articles in markdown. But the $ delimiters don't work inside <figcaption> tags, which are nested inside <figure> tags.

I guess that's because (part of) pelican-katex is a python-markdown extension, and python-markdown says it's supposed to follow John Gruber's markdown spec, and that spec says that text inside block-level HTML tags is not processed. <figure> is a block-level tag.

Incorrect result from markdown.util.etree.fromstring

System: Python 3.7.4 Win10
Python-Markdown: 3.2.1

https://github.com/cqql/pelican-katex/blob/def12d9254b7f5012ec84466ac84af3476ac40f8/pelican_katex/markdown.py#L41

produces nodes like '{http://www.w3.org/1998/Math/MathML}math' instead 'math' (also for all children of <math>) and these strings make it into the html output .
The result of the render_latex call in the preceding line seems to be correct, so something must happen in markdown.util.etree.fromstring (deprecated, by the way). But also when checking the underlying and now recommended xml.etree.elementTree the error is already visible there.

No obvious way to change or escape rendering delimiters

pelican-katex looks for a dollar sign after whitespace as an inline-math delimiter, but that catches a fair number of dollar literals for me; e.g. when representing USD ($5000.00), or assembly-style hexadecimal ($AF34).

I would like to either disable katex rendering for certain pages, or escape the delimiter as-needed. I suggest some combination of the following:

  • Allow escaping the delimiter with .
  • Allow changing or disabling the inline-math delimiter in pelicanconf.
  • Allow toggling katex rendering via a page metadata variable.

(it's possible a method already exists, but I looked and couldn't find one)

Error "unknown flag at position 11" in minimal example

Hi cqql!
we (@mtewes and @FKleinebreil) re trying to get a minimal pelican-katex example to work. We're using python 3.5.6, pelican 4.2.0, nodejs 0.1.1, pelican-katex 1.2.3.

As soon as we add PLUGINS = ["pelican_katex"] to the config, building the site fails with the error CRITICAL: error: unknown flag at position 11.

The actual page source seems not relevant for this error, but it is
A page source is :

Test
####

Test 

.. math::
	\pi = 3

Any ideas?

Math rendering in Atom/RSS feeds

  • Pelican: 4.8.0
  • pelican-katex version: f9d6fe3

Math formulas appear twice in Atom/RSS feeds.

Example

For instance, this page looks like this when rendered for the Web:

But in the Atom feed rendered in Thunderbird for the same paragraph appears as:

Probable cause

Diving a bit, I think the issue stems from neither CSS nor the KaTeX javascript being part of the <html>... headers in the feed. KaTeX renders MathML then HTML, and in the web version it is the HTML that is displayed and styled properly, while in the feed it is the MathML that renders properly (and then the HTML follows as redundant text).

Has someone already faced this issue and found a proper solution?

Ways forward

I see at least two options that could fix this:

  • Finding a way for the plugin not to generate the HTML for Atom/RSS feeds, leaving only the MathML (which is rendered OK most of the time).
  • Injecting KaTeX into the feed's headers so that e.g. Thunderbird here would render it properly. (Not sure if Thunderbird allows Javascript in feeds though, to be checked.)

Other suggestions?

Inline math following open bracket not possible

Hi, currently it is impossible to write something like some text ($x + y$) to get "some text ($x + y$)" (note that the parentheses are not in math mode) in pelican-katex due to the rule that inline math must be preceded by whitespace if it doesn't start at the beginning of a block.

Unlike false-positive cases where you don't want inline math but pelican-katex recognizes your markdown code as such—which you can fix by escaping the dollar sign—, this is an instance of a false-negative case that as far as I know has no possible workaround apart from inserting a space after the open bracket which you might not want.

A possible solution to the specific example above would be to also allow inline math to be preceded by ( (GitHub seems to handle this case similarly), but then there might be other false-negatives if someone wants to their inline math to follow a different character. I think that the only possible ways to always leave a choice to the user are to (1) assume math mode by default which the user has to escape if they don't want it or (2) do the reverse and require "inverted escaping" to enable math mode (which probably would be quite unintuitive).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.