Генерация MathJax в Hakyll: написание математических формул в markdown
Введение⌗
Hakyll - отличная система генерации статичных вэб-сайтов (блогов, персональных страничек, …), написанная на языке Haskell. Фактически же, hakyll
- это всего-навсего набор библиотек для сборки пользователем собственной Haskell-программы, которая и используется в дальнейшем для создания (генерации, обновления) статичных (HTML) вэб-страничек с использованием шаблонов.
На вход программе-генератору обычно поступают обыкновенные текстовые файлы в синтаксисе Markdown, в которых и содержится наполнение страниц сайта. Hakyll использует мощнейшую Haskell-библиотеку pandoc
для преобразования информации из Markdown в HTML и многие другие форматы.
Компилятор pandoc
, в частности, поддерживает рендеринг математических формул, записанных в тексте
Markdown в LaTex-нотации, в MathJax для последующей вставки (и отрисовывания браузером) в тело вэб-страницы.
По-умолчанию Hakyll вызывает pandoc
-компилятор с выключенной интерпретацией математических текстов.
Это легко настраивается и даёт удобную возможность писать сложные математические формулы прямо в
тексте markdown.
1. Изменение программы-генератора Hakyll⌗
Пырвый шаг - это модификация генератора.
Для рендеринга математики в интересующих нас .markdown
-файлов (у меня они хранятся в posts
), откроем Main.hs
генератора Hakyll и заменим дефолтную функцию pandocCompiler
(пакет pandoc
) на нашу собственную (с включёнными флагами MathJax):
-- Импортируем дополнительно
import qualified Data.Set as S
import Text.Pandoc.Options
{-
...
-}
-- Уравнение для нашей функции
pandocMathCompiler =
let mathExtensions = [Ext_tex_math_dollars, Ext_tex_math_double_backslash,
Ext_latex_macros]
defaultExtensions = writerExtensions defaultHakyllWriterOptions
newExtensions = foldr S.insert defaultExtensions mathExtensions
writerOptions = defaultHakyllWriterOptions {
writerExtensions = newExtensions,
writerHTMLMathMethod = MathJax ""
}
in pandocCompilerWith defaultHakyllReaderOptions writerOptions
main :: IO ()
main = do
{-
...
-}
-- Заменяем дефолтную функцию pandocCompiler на нашу
match "posts/*" $ do
route $ setExtension ".html"
compile $ do
pandocMathCompiler
>>= saveSnapshot "content"
>>= return . fmap demoteHeaders
>>= loadAndApplyTemplate "templates/post.html" (postCtx tags)
>>= loadAndApplyTemplate "templates/content.html" defaultContext
>>= loadAndApplyTemplate "templates/default.html" defaultContext
>>= relativizeUrls
{-
...
-}
Для моего генератора мне пришлось добавить зависимости containers
и pandoc
в .cabal
-файл.
2. Изменение HTML-шаблона⌗
Вторым шагом добавляем загрузку функционала MathJax в дефолтный шаблон (будущих) страничек с формулами (я добавил в <head>
файла templates/default.html
):
<!-- enable MathJax -->
<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
Ввод математики⌗
Для ввода LaTeX-математики в тексте Markdown теперь можно просто использовать двойной знак $:
Результат: $$ \ln x = \int_{-\infty}^x \frac 1 y \, dy $$
Результат: $$ \ln x = \int_{-\infty}^x \frac 1 y , dy $$
Ещё пример:
Текст в markdown:
$$
\require{AMScd}
\begin{CD}
K(X) @>{ch}>> H(X;\mathbb Q);\\
@VVV @VVV \\
K(Y) @>{ch}>> H(Y;\mathbb Q);
\end{CD}
$$
Текст в markdown:
$$
\require{AMScd}
\begin{CD}
K(X) @>{ch}» H(X;\mathbb Q);\
@VVV @VVV \
K(Y) @>{ch}» H(Y;\mathbb Q);
\end{CD}
$$
Всё работает на ура!