#!/usr/bin/env/python
# -*- coding:utf-8 -*-
"""
域公式转latex
域公式意义:\al 列内左对齐;\ac 列内居中对齐;\ar 列内右对齐
\r(,):根号;
\s(上标, 下标):设置上下标;
"""
import re, os
import configs
from pprint import pprint
from func_timeout import func_set_timeout
SUB = {"A":"Ⓐ",
"V":"Ⓥ",
"W":"Ⓦ",
"X":"Ⓧ",
"G":"Ⓖ",
}
def latex_wash(ltx, is_danti=0):
"""
latex格式调整, 为了渲染效果
:param ltx:
:return:
"""
# ltx = re.sub(r"(?|\s", "", s1)
# if not ss.group(2):
# eq_info = re.match(r"\$\s*(.+?)", item[ss.end():])
# if eq_info:
# s1 = "$_{{{sub}}}^{{{sup}}}$".format(sub=eq_info.group(1), sup=ss.group(1))
# s1 = re.sub("?su[bp]>|\s", "", s1)
# item = item[:ss.start()] + s1 + item[ss.end()+eq_info.end():]
# # return re.sub("?su[bp]>|\s", "", s1)
# else:
# item = item[:ss.start()] + s1 + item[ss.end():]
# else:
# item = item[:ss.start()] + s1 + item[ss.end():]
#
# # s1 = "$_{{{sub}}}^{{{sup}}}".format(sub=ss.group(2), sup=ss.group(1))
# # return re.sub("?su[bp]>|\s", "", s1)
# # item = re.sub(r"\$eq \\\\o\\\\al\((.+?),(.*?)\)", sub1, item)
#
# ac_info = re.search(r"\$eq \\\\o\\\\ac\(○,\s*([A-Z])\)", item)
# if ac_info:
# if ac_info.group(1) in SUB.keys():
# item = item.replace(ac_info.group(0), SUB.get(ac_info.group(1)))
#
# return item
# @func_set_timeout(3)
def get_latex0(item):
while "$eq \\\\f(" in item or "$eq \\\\r(" in item or re.search("【域公式】.*?\\\\o\\\\", item):
if "$eq \\\\f(" in item:
# item = re.sub(r"\$eq \\\\f\((((?!\\\\[fr]).)+?),(.+?)\)", r"$\\frac{\1}{\2}", item)
item = re.sub(r"(【域公式】.*?)\\\\f\((((?!\\\\[fr]\().)+?),(((?!\\\\[fr]\().)+?)\)",
r"\1\\frac{\2}{\4}", item)
if "$eq \\\\r(" in item:
item = re.sub(r"(【域公式】.*?)\\\\r\((((?!\\\\[fr]\().)+?)\)", r"\1\sqrt{\2}", item)
if re.search("【域公式】.*?\\\\o\\\\", item): # if "$eq \\\\o\\\\" in item:
while re.search(r"【域公式】.*?\\\\o\\\\al\((.+?),(.*?)\)", item):
ss = re.search(r"(【域公式】.*?)\\\\o\\\\al\((.+?),(.*?)\)", item)
# 将非变量的{}修改成{{}}
s1 = "_{{{sub}}}^{{{sup}}}".format(sub=ss.group(3), sup=ss.group(2))
s1 = re.sub("?su[bp]>|\s", "", s1)
if not ss.group(3):
eq_info = re.match(r"\$\s*(.+?)", item[ss.end():])
if eq_info:
s1 = "_{{{sub}}}^{{{sup}}}$".format(sub=eq_info.group(1), sup=ss.group(2))
s1 = re.sub("?su[bp]>|\s", "", s1)
item = item[:ss.start()] + ss.group(1) + s1 + item[ss.end()+eq_info.end():]
# return re.sub("?su[bp]>|\s", "", s1)
else:
item = item[:ss.start()] + ss.group(1) + s1 + item[ss.end():]
else:
item = item[:ss.start()] + ss.group(1) + s1 + item[ss.end():]
# s1 = "$_{{{sub}}}^{{{sup}}}".format(sub=ss.group(2), sup=ss.group(1))
# return re.sub("?su[bp]>|\s", "", s1)
# item = re.sub(r"\$eq \\\\o\\\\al\((.+?),(.*?)\)", sub1, item)
ac_info = re.search(r"\$eq \\\\o\\\\ac\(○,\s*([A-Z])\)", item)
if ac_info:
if ac_info.group(1) in SUB.keys():
item = item.replace(ac_info.group(0), SUB.get(ac_info.group(1)))
return item.replace("【域公式】$eq ", "$")
# @func_set_timeout(5)
def zifu_match_combine(split_eq):
"""
递归函数,将成对括号进行组合,目前先按成对的括号进行转化
:param split_eq:
:return:
"""
if len(split_eq) < 4 or ")" not in split_eq or "(" not in split_eq:
return split_eq
for k, i in enumerate(split_eq):
if i == ")":
for subk, j in enumerate(split_eq[:k][::-1]):
if j == "(":
# print(split_eq[k - subk - 1 - 1])
bef_left_kuohao = split_eq[k - subk - 1 - 1]
if bef_left_kuohao == "\\f":
# dou_index = split_eq[k-subk-1-1:k+1].index(',')+k-subk-2
# bb = split_eq[k - subk - 1 - 1:k + 1]
info1 = re.search(r"\\f\((.*?),(.*?)\)$", "".join(split_eq[k - subk - 1 - 1:k + 1]))
if info1:
new_s = "\\frac{{{one}}}{{{two}}}".format(one=info1.group(1), two=info1.group(2))
new_split_eq = split_eq[:k - subk - 1 - 1]
if new_split_eq and new_split_eq[-1] == "(":
new_s = "{" + new_s + "}"
new_split_eq.append(new_s)
new_split_eq.extend(split_eq[k + 1:])
return zifu_match_combine(new_split_eq)
elif bef_left_kuohao == "\\r":
print(':::', "".join(split_eq[k - subk - 1 - 1:k + 1]))
info1 = re.search(r"\\r\((.*?)\)$", "".join(split_eq[k - subk - 1 - 1:k + 1]))
if info1:
if re.search("\d\s*,", info1.group(1)):
lft, right = re.split("(?<=)\s*,", info1.group(1))
new_s = "\sqrt[{}]{{{}}}".format(re.search("(\d)", lft).group(1), right)
else:
new_s = "\sqrt{{{}}}".format(re.sub("^\s*,", "", info1.group(1)))
new_split_eq = split_eq[:k - subk - 1 - 1]
if new_split_eq and new_split_eq[-1] == "(":
new_s = "{" + new_s + "}"
new_split_eq.append(new_s)
new_split_eq.extend(split_eq[k + 1:])
return zifu_match_combine(new_split_eq)
elif bef_left_kuohao in ['\\o\\al', '\\s']:
info1 = re.search(r"(\\o\\al|\\s)\((.*?),(.*?)\)$", "".join(split_eq[k - subk - 1 - 1: k + 1]))
if info1:
new_s = "_{{{sub}}}^{{{sup}}}".format(sub=info1.group(3), sup=info1.group(2))
if info1.group(1) == "\\o\\al" and (not info1.group(3) or not info1.group(2)):
temp_s = info1.group(2) + info1.group(3)
temp_s_info1 = re.search("(.*?)",temp_s)
temp_s_info2 = re.search("(.*?)",temp_s)
if temp_s_info1 and temp_s_info2:
new_s = "_{{{}}}^{{{}}}".format(temp_s_info1.group(1), temp_s_info2.group(1))
new_s = re.sub("?su[bp]>|\s", "", new_s)
new_split_eq = split_eq[:k - subk - 1 - 1]
new_split_eq.append(new_s)
new_split_eq.extend(split_eq[k + 1:])
return zifu_match_combine(new_split_eq)
elif bef_left_kuohao == '\\x\\to':
info1 = re.search(r"\\x\\to\((.*?)\)$", "".join(split_eq[k - subk - 1 - 1:k + 1]))
if info1:
new_s = "\\bar{{{}}}".format(info1.group(1))
new_split_eq = split_eq[:k - subk - 1 - 1]
if new_split_eq and new_split_eq[-1] == "(":
new_s = "{" + new_s + "}"
new_split_eq.append(new_s)
new_split_eq.extend(split_eq[k + 1:])
return zifu_match_combine(new_split_eq)
else:
new_s = "".join(split_eq[k - subk - 1 - 1: k + 1])
new_split_eq = split_eq[:k - subk - 1 - 1]
new_split_eq.append(new_s)
new_split_eq.extend(split_eq[k + 1:])
return zifu_match_combine(new_split_eq)
# @func_set_timeout(36)
def get_latex(item, is_reparse=0, wordid="123456", must_latex=0):
"""
第一通道:
将文本中的域代码字符串能转化latex的先转化,不能转化的就暂时用域代码格式
第二通道:
再解析时,遇到域代码,将域代码转图片处理
考虑先转化:根式、分式、上下标、to、\s
:param item:
:return:
"""
is_first = 1
item = item.replace("\\uf028", "(").replace("\\uf029", ")") # 2020-6-21
new_item = item
# semi_succ_dict = {}
while re.findall("(【域公式:[^【]*?】)", item):
all_eqs1 = re.findall("(【域公式:[^【]*?】)", item) # 遇到嵌套的域公式,无法获取完整,故加【
all_eqs = list(set(all_eqs1))
all_eqs.sort(key=all_eqs1.index)
print(all_eqs)
new_eqs = []
fail_n = 0
for eq in all_eqs:
raw_eq = eq.replace("\\\\", "\\").replace(" \R", " \\r")
eq = raw_eq.replace("eq ", "").replace("【域公式:", "").replace("】", "")
split_eq = re.split(r"(\\f|\(|\)|\\r|\\o\\al|\\x\\to|\\s|,)", eq)
split_eq = [i for i in split_eq if i]
res_eq = zifu_match_combine(split_eq)
# print(res_eq, split_eq)
try:
if "".join(res_eq) == "".join(split_eq): # 转失败
fail_n += 1
new_eqs.append(raw_eq)
elif re.search(r"\\[a-zA-Z\d]{1,5}\(", "".join(res_eq)): # 没有完全转成功
fail_n += 1
new_eqs.append(raw_eq)
# semi_succ_dict[raw_eq] = "【域公式:eq {}】".format("".join(res_eq))
# new_eqs.append("【域公式:eq {}】".format("".join(res_eq)))
else:
# mathjax不能渲染sub和sup
new_eq = "".join(res_eq)
def deal2(yy):
new_y = yy.group(2)
if yy.group(1) == "":
new_y = "_{" + yy.group(2) + "}"
if yy.group(1) == "":
new_y = "^{" + yy.group(2) + "}"
return new_y
new_eq = re.sub("()(.+?)", deal2, new_eq)
new_eq = re.sub("()(.+?)", deal2, new_eq).strip()
if not is_first: # 如果不是第一轮转化,则将前面转化后的$去掉
new_eq = re.sub(r"(?(.+?)", r"\s(,\1)", eqs)
eqs = re.sub("(.+?)", r"\s(\1,)", eqs)
new_eqs2raw[eqs]=raw_eq
except:
pass
else:
eqs = re.sub("(.+?)", r"\s(,\1)", i.group(1))
eqs = re.sub("(.+?)", r"\s(\1,)", eqs)
new_eqs2raw[eqs] = i.group(0)
else:
print("域公式中含latex表达式!!!")
new_eqs = list(new_eqs2raw.keys())
new_eqs.append(file_path)
eqcode = "】【".join(new_eqs)
try:
requests.get(r"http://localhost:9001/FieldEq/Eq2Png/?eqcode=" + eqcode, timeout=3)
except:
pass
# 在生成图片的文件夹中对应判断图片再进行替换
eq_imgs = os.listdir(file_path)
if eq_imgs:
raw_eqs2img = {}
for img in eq_imgs:
w_h_info = str(img.replace(".png", "").split("__")[-1]).split("_")
w = int(int(w_h_info[0])/1.27+1)
h = int(int(w_h_info[1])/1.27+1)
name = str(img.replace(".png", "").split("__")[0])
idn = int(name.split("_")[-1])
new_name = name + ".png"
os.rename(file_path + "/" + img, file_path + "/" + new_name)
eq_img = ''\
.format(configs.new_img_ip, wordid, new_name, w, h, new_eqs[idn-1])
raw_eqs2img[new_eqs2raw[new_eqs[idn-1]]] = eq_img
if raw_eqs2img:
for k, v in raw_eqs2img.items():
item = item.replace(k, v)
new_item = new_item.replace(k, v)
else:
new_item = ""
else:
new_item = ""
return item, new_item
if __name__ == '__main__':
import requests,json
# f = "t=【域公式】$eq \\\\f(v0,a)$=【域公式】$eq \\\\f(6,1)$ s=6s, $eq \\\\r(6)$ "
# print(re.sub(r"\\\\o\\\\al\((.+?),.+?\)", r"\1",f))
# p1 = r"C:\Users\Python\Desktop\test\24\25.html"
# html = open(p1, 'r', encoding='utf-8').read()
# # print(html)
# print(get_latex(html))
# f = "eq \\f(\\f(1,2)×0.82,0.2×10)】【eq \\f(6,1)】【eq \\f(\\x\\to(OC)-\\x\\to(OA),2T)】【C:/Users/Python/Desktop/test/temp"
# res = requests.get(r"http://localhost:9001/FieldEq/Eq2Png/?eqcode=" + f, timeout=30).text
# print(json.loads(res).replace("\r\n", ""))
# f = "【解】解析 (1)因OB绳处于竖直方向,所以B球处于平衡状态,AB绳上的拉力为零,OB绳对小球的拉力FOB=mg. (3分)
(2)A球在重力mg、水平拉力F和OA绳的拉力FOA三力作用下平衡,所以OA绳对小球的拉力FOA=【域公式:eq \\\\f(mg,cos 60°)】=2mg. (3分)
(3)作用力F=mgtan 60°=【域公式:eq \\\\r(3)】mg. (3分)
答案 (1)mg (2)2mg (3)【域公式:eq \\\\r(3)】mg"
# f = "B.【域公式:eq \\r(3,\\f(1,4))】"
# f1 = "由动能定理得-W克f-mgh=0-【域公式:eq \\f(1,2)】mv【域公式:eq \\o\\al(B2,)】"
# aa = get_latex(f1, 1)
# print(aa)
# tt = r"${ } _ { n H C H O } \rightarrow f H _ { 2 } C - O _ { n }$"
# def sub1(ss):
# if re.search(r"\\left.*?\\right|\\right.*?\\left", ss.group(1)) is None:
# # res = re.sub(r"\\left(?!right|arrow)|\\right(?!left|arrow)", "", ss.group(1))
# res = re.sub(r"\\left(?![a-z])|\\right(?![a-z])", "", ss.group(1))
# return res
# return ss.group(1)
# tt = re.sub(r"(\$.*?(\\left(?![a-z])|\\right(?![a-z])).*?\$)", sub1, tt)
# # re1 = latex_wash(tt)
# print(tt)
# item = "【域公式:eq \\f(【域公式:eq \\f(6,1)】,3)】geeghe】threthtrh"
# new_eqs2raw = {} # 域代码_原始文本
# for i in re.finditer("【域公式:(.*?)】", item):
# print(i.group(0))
# if re.search(r"\\sqrt|\\frac|\\bar", i.group(1)) is None: # 不能包含latex命令
# if "【" in i.group(1): # 嵌套
# cout = i.group(1).count("【")
# try: # 根据嵌套的【找到最外层的】
# raw_eq = i.group(0) + "】".join(item[i.end():].split("】")[:cout]) + "】"
# eqs = i.group(1) + "".join(item[i.end():].split("】")[:cout])
# eqs = "eq " + eqs.replace("【域公式:", "").replace("【", "").replace("eq ", "")
# eqs = re.sub("(.+?)", r"\s(,\1)", eqs)
# eqs = re.sub("(.+?)", r"\s(\1,)", eqs)
# new_eqs2raw[eqs] = raw_eq
# except:
# pass
# else:
# eqs = re.sub("(.+?)", r"\s(,\1)", i.group(1))
# eqs = re.sub("(.+?)", r"\s(\1,)", eqs)
# new_eqs2raw[eqs] = i.group(0)
# 导入comtypes模块