iOS-LaTex,KaTex的加載
前言
最近項(xiàng)目里,需要一個(gè)控件加載HTML字符串,加載的控件百度上一堆, YYLabel,DTCoreText等都可以加載,實(shí)在不行還可以用UIWebView比較厚重的控件來(lái)實(shí)現(xiàn)。
YYLabel,DTCoreText 根據(jù)文本內(nèi)容直接可以同步計(jì)算出需要的高度,相較于UIWebView需要通過(guò)delegate的方法來(lái)實(shí)現(xiàn),實(shí)在不要太爽。
然鵝,最后發(fā)現(xiàn) $Na_{2}CO_{3}$ 這樣的格式。不能正確的顯示出來(lái),即 Latex
什么是LaTex?
LaTeX(LATEX,音譯“拉泰赫”)是一種基于ΤΕΧ的排版系統(tǒng),由美國(guó)計(jì)算機(jī)學(xué)家萊斯利·蘭伯特(Leslie Lamport)在20世紀(jì)80年代初期開(kāi)發(fā),利用這種格式,即使使用者沒(méi)有排版和程序設(shè)計(jì)的知識(shí)也可以充分發(fā)揮由TeX所提供的強(qiáng)大功能,能在幾天,甚至幾小時(shí)內(nèi)生成很多具有書(shū)籍質(zhì)量的印刷品。對(duì)于生成復(fù)雜表格和數(shù)學(xué)公式,這一點(diǎn)表現(xiàn)得尤為突出。因此它非常適用于生成高印刷質(zhì)量的科技和數(shù)學(xué)類(lèi)文檔。這個(gè)系統(tǒng)同樣適用于生成從簡(jiǎn)單的信件到完整書(shū)籍的所有其他種類(lèi)的文檔
簡(jiǎn)單點(diǎn)就是新的排版系統(tǒng),主要用于數(shù)學(xué)公式等,化學(xué)公式等等,作為一個(gè)教學(xué)類(lèi)的APP,不免會(huì)出現(xiàn)這樣的格式。躲是躲不過(guò)了!
怎么辦?
查找資料發(fā)現(xiàn),Latex這種格式的文本,無(wú)論是iOS還是在Android上,底層都是通過(guò)一個(gè)Web的方式來(lái)渲染。
- 方法1,使用YYLable加載文本,然后在
$Na_{2}CO_{3}$LaTex的地方,通過(guò)WebKit,加載出來(lái),整體上是YYLabel+WKWebView的方式來(lái)實(shí)現(xiàn),YYLabel負(fù)責(zé)加載富文本,WKWebView負(fù)責(zé)加載LaTex,如下圖

外面是YYLabel中間是WKWebView,可以參考SPMathKit的實(shí)現(xiàn)。 - 方法2,將LaTex做成PDF,然后加載到LaTex的地方,和方法一基本上雷同。
我采用的是第一種方法,然鵝,出其不意,富文本里面竟然有table
table的加載
無(wú)論是YYLable 還是DTCoreText都無(wú)法顯示完整的Table,表格視圖,最后只能用最笨重的方法實(shí)現(xiàn),使用UIWebView來(lái)加載Latex和Table,Table可以不添加script就能實(shí)現(xiàn),Latex需要添加JS,
實(shí)現(xiàn)思路,在HTML的字符串中給 Latex 加上一個(gè)class,然后包在一個(gè)HTML網(wǎng)頁(yè)中,加載這個(gè)網(wǎng)頁(yè),
最后的實(shí)現(xiàn)
新建一個(gè)類(lèi)繼承于UIWebView
處理字符串中,含有LaTex的部門(mén)加上class,
-(void)dealWithHTMLString:(NSString *)html{
NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil];
// 是否有$ ,有表示的含有LaTex
if([html rangeOfString:@"$"].location != NSNotFound) { // Expression inside text.
NSRange r;
BOOL intex = NO; // 判斷是前面的$還是后面的$,需要一對(duì)
while ((r = [html rangeOfString:@"$"]).location != NSNotFound) {
html = [html stringByReplacingCharactersInRange:r withString:(intex ? @"</span>" : @"<span class=\"tex\">")];
intex = !intex;
}
if (intex) NSLog(@"沒(méi)有閉合");
}
// 將處理后的字符串,嵌套在index.html中
appHtml = [appHtml stringByReplacingOccurrencesOfString:@"$LATEX$"
withString:html];
NSURL *baseURL = [NSURL fileURLWithPath:htmlPath];
[self setDelegate:self];
[self loadHTMLString:appHtml baseURL:baseURL];;
}
Index.html
<!DOCTYPE html>
<!-- saved from url=(0028)http://khan.github.io/KaTeX/ -->
<html class="wf-proximanova-i6-active wf-proximanova-n3-active wf-proximanova-n4-active wf-proximanova-n6-active wf-active"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
<link rel="stylesheet" type="text/css" href="katex.min.css">
<script src="katex.min.js" type="text/javascript"></script>
</head>
<body>
<div>$LATEX$</div>
<script type="text/javascript">
// 對(duì) clsss = tex 進(jìn)行處理
window.startup = function() {
function onload() {
var texes = document.getElementsByClassName('tex');
for(var i=0; i<texes.length; i++) {
katex.render(texes[i].innerHTML, texes[i]);
}
}
onload();
}
startup();
</script>
</body>
</html>
以上.
DEMO