問題
之前數學OCR渲染數學公式用的 katex 來渲染,前端解決方案,我們的進行公式編寫的時候是需要輸入中文的,如:
Fe_{2}O_{3} + 3 C O \stackrel{高溫}{=} 2 F e + 3CO_{2}
抑或:
c = \sqrt{a^{平方}+b_{xy}^{平方}+e^{x次方}}
在上篇 解決Latex輸出PDF紙張自適應大小及中文無法顯示問題,需要支援化學式識別,我們的服務是支援全量的latex語法,所以化學式和資料公式統一使用新服務來進行識別,畢竟katex就是latex的一個快速web數學公式渲染器,現在把兩個公式合併一下在我們的服務上渲染一下試試
Fe_{2}O_{3} + 3 C O \stackrel{高溫}{=} 2 F e + 3CO_{2}\\c = \sqrt{a^{平方}+b_{xy}^{平方}+e^{x次方}}
WTF! 中文的問題不是解決了嗎?怎麼又出問題了, 已經對中文進行了處理,怎麼不生效了?
一些例子:
Fe_{2}O_{3} + 3 C O \stackrel{HighTemperature}{=} 2 F e + 3CO_{2}測試中文
Fe_{2}O_{3} + 3 C O \stackrel{HighTemperature}{=} 2 F e + 3CO_{2}$測試中文
Fe_{2}O_{3} + 3 C O \stackrel{\mbox{高溫}}{=} 2 F e + 3CO_{2}
分析
行內公式和行間公式
latex中行內公式和行間公式分別使用 $ 和 $$ 來作為公式的起止符,如果在行內公式顯示中文則需要用\mbox{}來包裹中文,這樣中文就能在公式中正常顯示
之前我們直接在chemfig公式後面直接輸入中文,由於chemfig有明顯起始判斷,我們的中文latex並沒有識別為公式的一部分,所以能正常顯示,一旦我們在公式內部使用中文,仍然會出現中文無法渲染的問題,不過這個問題在katex下是不存在,應當是katex做了適配
解決辦法
方案一:按照標準的latex語法來,使用者在輸入公式的時候對中文部分自行加入 \mbox{} 或在公式結束位置標記 $結束符,這樣行內公式和公式外的中文就能正常顯示,合情合理
方案二:由於數學公式沒有明顯起始標識,所以可以在把傳入的字元中所有的連續中文在後臺用 \mbox{} 包裹起來,需要在程式碼中手動擷取相應的連續中文並使用mbox包裹即可
解決
毫無疑問,為了保持使用者使用的慣性,採取方案二,上程式碼
def with_mbox(mix_str):
""" 混合字串自動填充mbox
:param mix_str: chemfig表示式
:return: 自動包裹連續中文的chemfig表示式
"""
flag = False
t = ''
for char in mix_str:
if not flag and is_chinese(char):
flag = True
t += "\\mbox{" + char
elif flag and not is_chinese(char):
t += "}" + char
flag = False
elif is_chinese(char):
t += char
else:
t += char
flag = False
if is_chinese(t[len(t) - 1]):
t += "}"
return t
def is_chinese(check_char):
""" 檢查是否中文字元,含中文標點
:param check_char: 字元
:return: True|False
"""
if u'\u4e00' <= check_char <= u'\u9fff' or is_zw_punctuation(check_char):
return True
return False
def is_zw_punctuation(char_arr):
punctuation = """!?。。《》"#$%&'()*+-/:;<=>@[\]^_`{|}~⦅⦆「」、、〃》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〾〿–—‘'‛“”„‟…‧﹏"""
re_punctuation = "[{}]+".format(punctuation)
result = re.match(re_punctuation, char_arr)
return result is not None
使用前呼叫一下with_mbox方法 chem_fig = with_mbox(request.json['chemfig'])
完美解決
參考連結
TeX,LaTeX和KaTeX簡介:https://blog.csdn.net/wobushisongkeke/article/details/99677578
python 匹配中文字元:https://www.cnblogs.com/iamjqy/p/6824297.html