diff --git a/KatexMathView.swift b/KatexMathView.swift
index efe6eb1..f296582 100644
--- a/KatexMathView.swift
+++ b/KatexMathView.swift
@@ -8,38 +8,42 @@
import UIKit
import WebKit
-class KatexMathView: WKWebView {
-
+public class KatexMathView: WKWebView {
+ public var onLoaded: (CGFloat)-> Void = { _ in }
+
func loadLatex(_ content: String ) {
-
+#if SPM_PACKAGE
+ guard let path = Bundle.module.url(forResource: "katex/index", withExtension: "html")?.path else {
+ fatalError()
+ }
+#else
guard let path = Bundle.main.path(forResource: "katex/index", ofType: "html") else {
fatalError()
}
+#endif
self.configuration.preferences.javaScriptEnabled = true
- self.scrollView.isScrollEnabled = false
- self.scrollView.bounces = false
self.navigationDelegate = self
-
+
self.isOpaque = false
self.backgroundColor = UIColor.clear
self.scrollView.backgroundColor = UIColor.clear
-
+
let htmlContent = getHtml(content, path)
-
+
self.loadHTMLString(htmlContent, baseURL: URL(fileURLWithPath: path))
}
-
+
func getHtml(_ htmlContent: String, _ path: String) -> String {
-
+
var htmlString = try! String(contentsOfFile: path, encoding: .utf8)
-
+
var content = htmlContent
let delimitter = "$"
let startTexTag = ""
let endTexTag = ""
-
+
var first = true
-
+
while content.contains(delimitter) {
let tag: String = first ? startTexTag : endTexTag
if let range = content.range(of: delimitter) {
@@ -50,24 +54,24 @@ class KatexMathView: WKWebView {
htmlString = htmlString.replacingOccurrences(of: "$LATEX$", with: content)
return htmlString
}
-
-
-
+
+
+
}
extension KatexMathView : WKNavigationDelegate {
-
+
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
- self.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
+ self.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
self.frame.size.height = height as! CGFloat
self.layoutIfNeeded()
+ self.onLoaded(self.frame.size.height)
})
}
-
+
})
}
-
-}
+}
diff --git a/KatexView.swift b/KatexView.swift
new file mode 100644
index 0000000..19fe901
--- /dev/null
+++ b/KatexView.swift
@@ -0,0 +1,78 @@
+import SwiftUI
+import WebKit
+
+public struct KatexView: View {
+ private let latex: String
+
+ @State
+ private var contentHeight: CGFloat = 0
+
+ @State
+ private var isLoaded = false
+
+ public init(latex: String) {
+ self.latex = latex
+ }
+
+ public static func resetHeightCache() {
+ KatexMathViewRepresentable.heightCache = [Int: CGFloat]()
+ }
+
+ public var body: some View {
+ ZStack {
+ KatexMathViewRepresentable(latex: latex, contentHeight: $contentHeight, isLoaded: $isLoaded)
+ .frame(height: contentHeight)
+ if !isLoaded {
+ ProgressView()
+ }
+ }.frame(maxWidth: .infinity)
+ }
+}
+
+struct KatexMathViewRepresentable: UIViewRepresentable {
+ // Caching heights prevents jumpy UI since the height calculation is
+ // delayed only the first time the latex block is rendered.
+ static var heightCache = [Int: CGFloat]()
+
+ private let latex: String
+
+ private let uiView = KatexMathView()
+
+ @Binding var contentHeight: CGFloat
+ @Binding var isLoaded: Bool
+
+ init(latex: String, contentHeight: Binding, isLoaded: Binding) {
+ self.latex = latex
+ self._contentHeight = contentHeight
+ self._isLoaded = isLoaded
+ }
+
+ func katexMathView(_ katexMathView: (KatexMathView) -> Void) -> KatexMathViewRepresentable {
+ katexMathView(uiView)
+ return self
+ }
+
+ func makeUIView(context: Context) -> KatexMathView {
+ uiView.onLoaded = { height in
+ isLoaded = true
+ contentHeight = height
+ var hasher = Hasher()
+ hasher.combine(latex)
+ Self.heightCache[hasher.finalize()] = height
+ }
+ return uiView
+ }
+
+ public func updateUIView(_ uiView: KatexMathView, context: Context) {
+ var hasher = Hasher()
+ hasher.combine(latex)
+ let hash = hasher.finalize()
+
+ if let height = Self.heightCache[hash] {
+ DispatchQueue.main.async {
+ contentHeight = height
+ }
+ }
+ uiView.loadLatex(latex)
+ }
+}
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000..5cfbf87
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,33 @@
+// swift-tools-version:5.3
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+import PackageDescription
+
+let package = Package(
+ name: "KatexMathView",
+ platforms: [.iOS(.v14), .macOS(.v11)],
+ products: [
+ .library(
+ name: "KatexMathView",
+ targets: ["KatexMathView"])
+ ],
+ targets: [
+ .target(
+ name: "KatexMathView",
+ path: ".",
+ exclude: [
+ "Example",
+ "README.md",
+ ],
+ sources: [
+ "KatexMathView.swift",
+ "KatexView.swift",
+ ],
+ resources: [
+ .copy("katex")
+ ],
+ swiftSettings: [
+ .define("SPM_PACKAGE")
+ ]
+ )
+ ]
+)
diff --git a/katex/katex.css b/katex/katex.css
index 19f30c4..c94f828 100644
--- a/katex/katex.css
+++ b/katex/katex.css
@@ -1022,5 +1022,13 @@
img {
max-width:100% !important;
width:100% !important;
-
+}
+
+* {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+}
+
+:root {
+ color-scheme: light dark;
}
diff --git a/katex/katex.min.css b/katex/katex.min.css
index b2d4dc3..c2f6a4f 100644
--- a/katex/katex.min.css
+++ b/katex/katex.min.css
@@ -2,5 +2,14 @@
img {
max-width:100% !important;
width:100% !important;
-
+
+}
+/* Disable touch and text-selection. */
+* {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+}
+
+:root {
+ color-scheme: light dark;
}