让 Hexo 主题支持 LaTeX

让 Hexo 主题支持 LaTeX

前提紧要

  • 我很长一段时间使用基于 MDUI 开发的 Hexo 主题 Default 。我很欣赏它的 Material Design 风格。但我每欲写数学公式,它就提醒我它没有 LaTeX 支持。它该改了。

开始

更换渲染引擎

  • 在博客根目录启动终端执行:
1
2
npm uninstall hexo-renderer-marked
npm install hexo-renderer-kramed --save
  • 此举将使 Hexo 从 hexo-renderer-marked 切换到 hexo-renderer-kramed 。

安装插件

  • 在博客根目录启动终端执行:
1
npm install hexo-renderer-markdown-it-plus --save

修改配置文件

  • 编辑博客根目录下的 _config.yml 文件,在文件尾部添加:
1
2
3
4
5
6
7
8
9
10
11
12
13
markdown_it_plus:
highlight: true
html: true
xhtmlOut: true
breaks: false
langPrefix:
linkify: true
typographer: false
quotes:
plugins:
- plugin:
name: markdown-it-mark
enable: false
  • 接下来,我应该修改 /themes/$your_theme_name/layout$your_theme_name 指的是你的主题名称)下的 _layout.swig 文件并在 <head>……</head> 之间靠近尾部添加:
1
2
3
4
<% if (page.mathjax) { %>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js" integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz" crossorigin="anonymous"></script>
<% } %>
  • 然而我的目录下并没有 _layout.swig 文件,取而代之是 layout.ejs 文件。其内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="<%= page.lang %>">
<%- partial('_partial/head') %>
<body class="mdui-appbar-with-toolbar mdui-theme-primary-<%= theme.theme_color.primary || 'indigo' %> mdui-theme-accent-<%= theme.theme_color.accent || 'pink' %>">
<script>var a=localStorage.getItem("mdui-theme-layout-dark");if(a){document.getElementsByTagName("body")[0].className+=" mdui-theme-layout-dark"};</script>
<script>if(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches){document.getElementsByTagName("body")[0].className+=" mdui-theme-layout-dark"};</script>
<script>var a=localStorage.getItem("mdui-drawer-close");if(!a){document.getElementsByTagName("body")[0].className+=" mdui-drawer-body-left"};</script>
<%- partial('_partial/header', null, {cache: !config.relative_link}) %>
<%- partial('_partial/sidebar', null, {cache: !config.relative_link}) %>
<main id="main" class="mdui-m-t-5 fadeIn animated"><%- body %></main>
<%- partial('_partial/footer', null, {cache: !config.relative_link}) %>
<button id="gotop" class="mdui-fab mdui-fab-fixed mdui-fab-hide mdui-color-theme-accent mdui-ripple"><i class="mdui-icon material-icons">arrow_upward</i></button>
<% if (theme.busuanzi.site || theme.busuanzi.page) { %><script async src="<%- theme.busuanzi.busuanzi_js %>"></script><% } %>
<%- js(['js/mdui', 'js/script']) %>
<%- js('custom') %>
</body>
</html>
  • 我注意到第三行的 <%- partial('_partial/head') %> 项将 <head>……</head> 引到了 \themes\default\layout\_partial\head.ejs 文件内:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Cache-Control" content="no-siteapp">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="renderer" content="webkit">

<%
var title = page.title;
if (is_archive()) {
title = __('archive');
if (is_month()) {
title += ': ' + page.year + '/' + page.month;
} else if (is_year()) {
title += ': ' + page.year;
}
} else if (is_category()) {
title = __('category') + ': ' + page.category;
} else if (is_tag()) {
title = __('tag') + ': ' + page.tag;
}
%>
<title><% if (title) { %><%= title %> | <% } %><%= config.title %></title>

<% if (theme.favicon) { %><%- favicon_tag(theme.favicon) %><% } %>
<% if (theme.rss) { %><%- feed_tag(theme.rss, {title: config.title}) %><% } %>
<%- open_graph({twitter_id: theme.open_graph.twitter, google_plus: theme.open_graph.google_plus, fb_admins: theme.open_graph.fb_admins, fb_app_id: theme.open_graph.fb_app_id}) %>

<meta name="keywords" content="<% if (page.tags && page.tags.each) { page.tags.each(function (tag) { %><%= ',' + tag.name %><% })} else if (config.keywords) { %><%= config.keywords %><% } %>">
<meta name="format-detection" content="telephone=no,email=no">
<meta name="theme-color" content="#9C27B0">

<meta name="mobile-web-app-capable" content="yes">
<meta name="application-name" content="<%= config.title %>">
<meta name="msapplication-starturl" content="<%- config.url + url_for(page.path).replace('index.html', '') %>">
<meta name="msapplication-navbutton-color" content="#9C27B0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="<%= config.title %>">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon" href="<%- url_for(theme.favicon) %>">

<% if (page.current === 1 && is_home()) { %>
<link rel="canonical" href="<%- config.url %>">
<% } else { %>
<link rel="canonical" href="<%- config.url + url_for(page.path) %>">
<% } %>

<% if (theme.site_verification.google) { %><meta name="google-site-verification" content="<%= theme.site_verification.google %>"><% } %>
<% if (theme.site_verification.baidu) { %><meta name="baidu-site-verification" content="<%= theme.site_verification.baidu %>"><% } %>

<% if (theme.analytics.google_site_id) { %><%- partial('_widget/analytics/google-analytics') %><% } %>
<% if (theme.analytics.baidu_site_id) { %><%- partial('_widget/analytics/baidu-analytics') %><% } %>
<% if (theme.analytics.cnzz_site_id) { %><%- partial('_widget/analytics/cnzz-analytics') %><% } %>

<%- css(['css/mdui', 'css/style']) %>
<%- css('custom') %>
</head>
  • 修改后:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Cache-Control" content="no-siteapp">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="renderer" content="webkit">

<%
var title = page.title;
if (is_archive()) {
title = __('archive');
if (is_month()) {
title += ': ' + page.year + '/' + page.month;
} else if (is_year()) {
title += ': ' + page.year;
}
} else if (is_category()) {
title = __('category') + ': ' + page.category;
} else if (is_tag()) {
title = __('tag') + ': ' + page.tag;
}
%>
<title><% if (title) { %><%= title %> | <% } %><%= config.title %></title>

<% if (theme.favicon) { %><%- favicon_tag(theme.favicon) %><% } %>
<% if (theme.rss) { %><%- feed_tag(theme.rss, {title: config.title}) %><% } %>
<%- open_graph({twitter_id: theme.open_graph.twitter, google_plus: theme.open_graph.google_plus, fb_admins: theme.open_graph.fb_admins, fb_app_id: theme.open_graph.fb_app_id}) %>

<meta name="keywords" content="<% if (page.tags && page.tags.each) { page.tags.each(function (tag) { %><%= ',' + tag.name %><% })} else if (config.keywords) { %><%= config.keywords %><% } %>">
<meta name="format-detection" content="telephone=no,email=no">
<meta name="theme-color" content="#9C27B0">

<meta name="mobile-web-app-capable" content="yes">
<meta name="application-name" content="<%= config.title %>">
<meta name="msapplication-starturl" content="<%- config.url + url_for(page.path).replace('index.html', '') %>">
<meta name="msapplication-navbutton-color" content="#9C27B0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="<%= config.title %>">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon" href="<%- url_for(theme.favicon) %>">

<% if (page.current === 1 && is_home()) { %>
<link rel="canonical" href="<%- config.url %>">
<% } else { %>
<link rel="canonical" href="<%- config.url + url_for(page.path) %>">
<% } %>

<% if (theme.site_verification.google) { %><meta name="google-site-verification" content="<%= theme.site_verification.google %>"><% } %>
<% if (theme.site_verification.baidu) { %><meta name="baidu-site-verification" content="<%= theme.site_verification.baidu %>"><% } %>

<% if (theme.analytics.google_site_id) { %><%- partial('_widget/analytics/google-analytics') %><% } %>
<% if (theme.analytics.baidu_site_id) { %><%- partial('_widget/analytics/baidu-analytics') %><% } %>
<% if (theme.analytics.cnzz_site_id) { %><%- partial('_widget/analytics/cnzz-analytics') %><% } %>

<%- css(['css/mdui', 'css/style']) %>
<%- css('custom') %>
<% if (page.mathjax) { %>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js" integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz" crossorigin="anonymous"></script>
<% } %>
</head>

标记渲染文章

  • 假如要在某一个文章启用 LaTeX。在开头博文属性栏添加属性:
1
mathjax: true
作者

PJ568

发布于

2023-04-13

更新于

2024-08-28

许可协议

评论