惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
人人都是产品经理
人人都是产品经理
博客园 - 三生石上(FineUI控件)
aimingoo的专栏
aimingoo的专栏
U
Unit 42
GbyAI
GbyAI
H
Help Net Security
A
Arctic Wolf
SecWiki News
SecWiki News
K
Kaspersky official blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
Blog — PlanetScale
Blog — PlanetScale
B
Blog
Spread Privacy
Spread Privacy
L
Lohrmann on Cybersecurity
C
Check Point Blog
O
OpenAI News
Microsoft Security Blog
Microsoft Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
大猫的无限游戏
大猫的无限游戏
Google DeepMind News
Google DeepMind News
Webroot Blog
Webroot Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Palo Alto Networks Blog
A
About on SuperTechFans
S
SegmentFault 最新的问题
Recent Announcements
Recent Announcements
S
Schneier on Security
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
Jina AI
Jina AI
The Hacker News
The Hacker News
V2EX - 技术
V2EX - 技术
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
腾讯CDC
罗磊的独立博客
G
GRAHAM CLULEY
L
LINUX DO - 热门话题
雷峰网
雷峰网
博客园 - 【当耐特】
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
美团技术团队
M
MIT News - Artificial intelligence
Engineering at Meta
Engineering at Meta
Hacker News: Ask HN
Hacker News: Ask HN
S
Security Affairs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
月光博客
月光博客

hsfzxjy 的博客

解决 VSCode + CMake + MSVC 编译器信息乱码的问题 使用 3090 部署 1.58bit 动态量化版 DeepSeek R1 671b 如何在 VS Code DevContainer 中配置 HTTP 代理 如何在跳板机背后的服务器上使用 VS Code Remote - Containers Cohesive Digests for Ints and Floats Rust 中的隐匿概念 —— Place(位置) 美术馆 一尺之槌,日取其半,1075日而竭 老生常谈:使用 Cloudflare 自选 IP 加速站点访问 辩义 State、Nation 与 Country 将 Base64 编码的数据快速转换为 Uint8Array 折腾 NPU·第1章 —— 搭建 Level Zero 开发环境 折腾 NPU·第0章 —— Intel NPU 概述与 Level-Zero 新增域名 monad.run CSS 中为特定字符设置不同字体 Arbitary Lifetime Transmutation via Rust Unsoundness Dijkstra 算法的延伸 Manacher 回文计数算法 硬卧 Go Fact: Zero-sized Field at the Rear of a Struct Has Non-zero Size Display *big.Rat Losslessly and Smartly in Golang 代码的仪式 Building Electron From Scratch 中式亲属称谓研究之一:构建半群 Some Notes on Kotlin Coroutines Git sparse-checkout and partial clones for Mega-Repos 辩义“封建” Diving from the CUDA Error 804 into a bug of libnvidia-container Modern Cryptography, GPG and Integration with Git(hub) Move the Root Partition of Ubuntu A New Programmer Kicks a Roadblock Git-based Dependencies in Dart and Go Reversy Naming 人类一败涂地 Invalid Golang Pointers Can Bite You Even If You Don't Dereference Side Project(副业) A Flaw of Promoting Complex Trait Bounds in Rust Initialize Process Pool Worker with Individual Value Rust - Python FFI From Scratch [Extending Hexo For My Site] Part 0 Debug a 'torch.tensor(1).cuda()' hanging 不自由的互联网 Retrieve Contents over HTTP without curl or wget [Unravelling mocona] Part 1 - Verbosity or Anti-Pattern [Unravelling mocona] Part 0 - Preface Understanding pickle in Python Rough Notes on Deploying Vaultwarden & NextCloud Bookmarks 语言狂热者与实用主义者 Demystify the randomness in CUDA kernels Performant Bulk Mutations in IndexedDB Auto Rebuild .pyx Files with pyximport Cython and Threads Obtain a Random Available TCP Port with Bash Information Theory: KL Divergence Information Theory: Entropy and Mutual Information 铁板烧 西郊线 Proof of the Gumbel Max Trick Option::as_ref Rc, RefCell and Interior Mutability Visualizing Correlation 三月十日杂感 三月一日杂感 二月十一日杂感 一月二十六日杂感 SS Configuration 一月七日杂感 四月·病 Haskell 笔记:State Monad Haskell 笔记:Monad 引论 Haskell 笔记:Applicative Haskell 笔记:Category Theory and Functor Haskell 笔记:data, type, newtype Haskell 笔记:folds 使用 Aria2 在 Ubuntu 中下载百度云资源 从伪并行的 Python 多线程说起 一个 Reentrant Error 引发的对 Python 信号机制的探索和思考 Linux 文件权限 HSFZMUN 4.0 部署小记 午后雨·科大 最后的雨夜·广州 揭秘·变态的平方根倒数算法 神坑·Python 装饰类无限递归 Python“黑魔法”之 Encoding & Decoding Ubuntu 重新映射键盘布局 为什么我要翻墙 Python“黑魔法”之 Generator Coroutines 数学美 之 判断线段相交的最简方法 除夕杂感 17 行代码实现的简易 Javascript 字符串模板 Python“黑魔法”之 Meta Classes 诗集 生活,需要被“发现” 家书·十八岁成人礼 炫技?还是需求? 【译】响应式图片的现状 【译】“为什么有这么多的编程语言?” Wisecity 商赛总结——也谈前端自动化测试 记一次 DoS 诈骗网站的经历 那一年,我们望向星空
[Extending Hexo For My Site] Part 1
2022-01-03 · via hsfzxjy 的博客

I am a heavy user of Mathjax. Mathjax is a library that renders Tex-compatible syntax into pretty equations in web scenarios. Hence I am always mixing up Markdown and Tex snippets in my writing. The annoying part is Tex snippets have low priority in my Markdown renderer, and are sometimes incorrectly rendered into Markdown elements. For instance, $a_1, a_2$ becomes $a1, a2$, where underscores within $...$ are mistakenly recognized as an emphasis element. A bunch of escaping is required to avoid the situation, which drives me mad. So I got to seek a permanant solution.

The first attempt was to add specialized logic for Tex snippets into Markdown renderer, but I soon found it hardly a neat workaround. The renderer I use is marked. The package itself does not work alone, but depends on hexo-renderer-marked as a wrapper. If I would add magic in marked, I had to fork and edit both marked and hexo-renderer-marked. Also, parsing Tex snippets is something beyond the duty of a Markdown renderer. There is no reason to nail the two stuff together, and I gave up.

Then I came up with another idea: what if I “guard” the Tex snippets before feeding the content into Markdown renderer? By “guarding” I mean to replace Tex snippets by something that marked ignores, and restore them after marked finishes rendering.

Actually, Hexo DOES provide such an official trick, though it’s not mentioned in the docs. In short, you can wrap a piece of content with a special tag <hexoPostRenderCodeBlock >...</hexoPostRenderCodeBlock> in a before_post_render filter, to prevent it from being parsed by renderer. The code that handles the trick can be found at hexo/post.js. Before taken over by renderer, all <hexoPostRenderCodeBlock > tags will be detached and replaced by some special HTML comment tags like <--code\uFFFCxxx-->. After renderer finishes, each comment tag is substituted back to inner content of corresponding <hexoPostRenderCodeBlock > tag. Such usage exists both in Hexo built-in plugin and in the wild.

Our goal is clear now: build a before_post_render filter, which finds out each piece of legitimate Tex snippets, either inline-level $...$ or block-level $$...$$, and wraps them with the magical <hexoPostRenderCodeBlock > tag. The matching can be realized using simple regular expressions:

const rBlockMath = /^\$\$([^\$]+?)\$\$/gm
const rInlineMath = /(?<!\$)\$([^\$\n]+?)\$(?!\$)/g

rInlineMath contains certain assertions in case block-level snippets mistakenly being interpreted as inline ones. Such concern can alternatively be addressed by first matching block-level snippets and then inline ones, but I would rather use assertions for better clarification.

Beyond the regular expressions, there is still some edge cases that should be carefully taken into consideration – $ within code blocks should never be touched. Unfortunately, it’s not straightforward (or impossible) to achieve with mere regular expressions, since code block context is too complicated to match. A workaround here is required, that is to detach all code blocks beforehand, then handle the Tex snippets, and lastly restore the code blocks.

It’s also worth noting that before_post_render filters from other plugins can be executed prior to us, and thus <hexoPostRenderCodeBlock > tags can pre-exist in the content, whose inner texts are also expected to remain untouched. Our workaround then needs to handle three cases, magical tags and two forms of code blocks (single-backticked and triple-backticked).

But in fact, it is enough to consider only two of them. There’s a less known filter bundled in the built-in plugin named backtick_code_block. The filter syntax-highlights triple-backticked code blocks and guards them with the magical tag. At the time our filter gets executed, triple-backticked code blocks will have already been wrapped in <hexoPostRenderCodeBlock >, and no need to handle.

So here’s the pipeline: 1) find out all existing <hexoPostRenderCodeBlock > and single-backticked code blocks, and detach them; 2) find out all Tex snippets (inline or block-level), and wrap them with <hexoPostRenderCodeBlock > tag; 3) restore the aforementioned detached items. It’s also critical to register the filter with priority larger than 10, so that backtick_code_block filter will be called before us.

The filter mathjax is packed in plugin hexo-enhanced and the code at lib/filter/before_post_render/mathjax.js. With it enabled, you can now write math equations on the fly just like in a Tex file, without any burden of escaping special characters.


Author: hsfzxjy.
Link: .
License: CC BY-NC-ND 4.0.
All rights reserved by the author.
Commercial use of this post in any form is NOT permitted.
Non-commercial use of this post should be attributed with this block of text.