LaTex數學公式轉換--使用Katex

背景:試卷拆錄-圖片識別,產品需求:

  • 當識別結果中存在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 }} />
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章