解決latex數學公式渲染不正確及行內公式中文渲染亂碼問題


問題

之前數學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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM