From 49d6a9fbeb4b2342d51fd88bc5825bc14b033b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E5=8D=83=E9=87=8C?= Date: Wed, 24 Jun 2026 09:25:16 +0800 Subject: [PATCH] Render Zhihu latex equations --- .../platforms/__tests__/zhihu.test.ts | 27 ++++++++++++ packages/core/src/adapters/platforms/zhihu.ts | 43 +++++++++++++++++-- 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 packages/core/src/adapters/platforms/__tests__/zhihu.test.ts diff --git a/packages/core/src/adapters/platforms/__tests__/zhihu.test.ts b/packages/core/src/adapters/platforms/__tests__/zhihu.test.ts new file mode 100644 index 00000000..6cece957 --- /dev/null +++ b/packages/core/src/adapters/platforms/__tests__/zhihu.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from 'vitest' +import { ZhihuAdapter } from '../zhihu' + +describe('ZhihuAdapter', () => { + it('renders markdown latex as Zhihu equation images', () => { + const adapter = new ZhihuAdapter() + const transformContent = ( + adapter as unknown as { transformContent(content: string): string } + ).transformContent.bind(adapter) + + const html = [ + '

行内 $111$ 公式

', + '

$$x^2 + y^2$$

', + '

', + '
$keep$
', + ].join('') + + const result = transformContent(html) + + expect(result).toContain('https://www.zhihu.com/equation?tex=111') + expect(result).toContain('eeimg="1"') + expect(result).toContain('https://www.zhihu.com/equation?tex=x%5E2%20%2B%20y%5E2') + expect(result).toContain('eeimg="2"') + expect(result).toContain('
') + expect(result).toContain('
$keep$
') + }) +}) diff --git a/packages/core/src/adapters/platforms/zhihu.ts b/packages/core/src/adapters/platforms/zhihu.ts index c666414b..39d1aaf5 100644 --- a/packages/core/src/adapters/platforms/zhihu.ts +++ b/packages/core/src/adapters/platforms/zhihu.ts @@ -197,25 +197,60 @@ export class ZhihuAdapter extends CodeAdapter { // 1. 转换表格格式 - 知乎 Draft.js 编辑器需要特定格式 result = this.transformTables(result) - // 2. 图片格式 - 知乎需要 figure 包裹 + // 2. LaTeX 公式 - 知乎编辑器使用 equation 图片 + result = this.transformLatex(result) + + // 3. 图片格式 - 知乎需要 figure 包裹 result = result.replace( /]+)src="([^"]+)"([^>]*)>/gi, - '
' + (match, before, src, after) => { + if (src.startsWith('https://www.zhihu.com/equation?tex=')) return match + return `
` + } ) - // 3. 代码块格式 + // 4. 代码块格式 result = result.replace( /
/gi,
       '
'
     )
 
-    // 4. 移除微信样式属性 (但保留知乎的 data-draft-* 属性)
+    // 5. 移除微信样式属性 (但保留知乎的 data-draft-* 属性)
     result = result.replace(/\s*data-(?!draft)[a-z-]+="[^"]*"/gi, '')
     result = result.replace(/\s*style="[^"]*"/gi, '')
 
     return result
   }
 
+  private transformLatex(content: string): string {
+    return content
+      .split(/()/gi)
+      .map((chunk) => {
+        if (/^
+            this.zhihuEquationImage(latex, '2')
+          )
+          .replace(/\$([^$\n]+?)\$/g, (_match, latex) =>
+            this.zhihuEquationImage(latex, '1')
+          )
+      })
+      .join('')
+  }
+
+  private zhihuEquationImage(latex: string, eeimg: '1' | '2'): string {
+    const formula = latex.trim()
+    const encoded = encodeURIComponent(formula)
+    const alt = formula
+      .replace(/&/g, '&')
+      .replace(/"/g, '"')
+      .replace(//g, '>')
+
+    return `${alt}`
+  }
+
   /**
    * 转换表格为知乎 Draft.js 格式
    */