背景:試卷拆錄-圖片識別,產品需求:
- 當識別結果中存在LaTeX的文本時,需要轉換成與圖片中的文本一致;
- 展示識別結果,在識別結果前需要增加框的編號,如:【1】1. 下列屬於酸性氧化物的是;
一時間不知道咋搞, emm......
-
後面找資料發現了Katex組件,但是遇到了一個樣式不生效的問題;
-
後面又發現了react-katex,是基於Katex寫的關於react項目的,但是發現如果字符串中有中文的話報錯沒法用,目前需求中肯定是有中文的;
-
後面又發現了Tex,是基於react-katex修改的, 但是支持中文;
下面來具體講述我使用過程中遇到的一些問題以及解決方法。
一、Katex
1、官方git鏈接
https://github.com/KaTeX/KaTeX
2、安裝之後引入,直接根據文檔操作即可,我主要說下自己遇到的問題。
引入
import 'katex/dist/katex.min.css';
import katex from 'katex';
啓動的時候報錯,如下圖:
究其原因,katex.css中用的字體的原因。
@font-face {
font-family: 'KaTeX_AMS';
src: url(fonts/KaTeX_AMS-Regular.woff2) format('woff2'), url(fonts/KaTeX_AMS-Regular.woff) format('woff'), url(fonts/KaTeX_AMS-Regular.ttf) format('truetype');
font-weight: normal;
font-style: normal;
}
但是項目webpack中並沒有配置這種loader,因爲項目是nextjs的,在next.config.js中增加url-loader配置之後,重啓即可;
const urlLoaderRule = {
test: /\.(woff|woff2|ttf|svg)$/,
use: {
loader: 'url-loader',
options: {
limit: 100000,
}
}
}
config.module.rules.push(urlLoaderRule)
到現在終於是可用了,直接切入使用
3、開始使用
- mock數據
const resultList = [
{
text: ["1.在下列實數中,爲無理數的是()", "A.2B.-0.101001C.\sqrt{2}"],
},
{
text: ["2.點(1,-1)在()", "A.第一象限B.第二象限", "C.第三象限D.第四象限"],
}
]
- UI實現
因爲我這邊涉及到一個切換tab的功能,需要注意的是若是要保證追加結果的div一直是存在的,只能設置樣式display去隱藏或者顯示,如果直接用&&判斷(切換tab的時候將div刪除),結果將不能追加;如果不涉及tab切換的話不會有這個問題;
<div className={less.panel + ' ' + (this.state.currentIndex === 1 ? less.panelDisplay : '')} ref={(e) => this.state.textRef = e}>
{
resultList.length > 0 &&
resultList.map((textItem, index) => {
return (
this.identifyResultsShowing(textItem.text.join(' '), index)
);
})
}
</div>
- identifyResultsShowing函數實現
創建了p元素,2個span,一個span元素放題號,一個span放識別結果,最後,將p標籤追加到div中;
有不識別的中文或其他字符的話控制檯會報很多warning,如果你嫌煩,可以設置strict: 'ignore';
設置識別錯誤之後文本的顏色,errorColor: '#042044';
identifyResultsShowing(text, index) {
if (!this.state.textRef) {
return false;
}
let katexText = text.replace(/(\\n)/g, '\\n\\\\');
const pElement = document.createElement('p');
const spanElementIndex = document.createElement('span');
spanElementIndex.innerHTML = '【' + (index + 1) + '】';
pElement.appendChild(spanElementIndex);
const spanElement = document.createElement('span');
katex.render(katexText || '', spanElement, {
throwOnError: false,
errorColor: '#042044',
strict: 'ignore',
});
pElement.appendChild(spanElement);
this.state.textRef.appendChild(pElement);
}
到目前爲止,這個功能是可用的。但是項目是react,最好可以有匹配的組件,找了下確實有,哈哈。
二、react-katex
1、官方git鏈接
https://github.com/talyssonoc/react-katex
2、安裝引入,按照文檔即可,但是報錯如下:
最終發現不支持中文,也就是處理的字符串中不能有中文;果斷放棄。
三、Tex
1、官方git鏈接
https://github.com/MatejBransky/react-katex
2、安裝引入使用
按照文檔安裝引入使用即可,並且可以和Katex一樣設置一些屬性,有興趣的可以嘗試,這個我沒有用到項目中,但是我後面會試試,試完之後再贅述。
四、總結
看了react-katex和Tex的源碼之後發現核心就是都用了dangerouslySetInnerHTML,在一個dom裏直接篩入一段純html。
<Component {...otherProps} dangerouslySetInnerHTML={{ __html: html }} />