我该如何在SwiftUI中使用LaTeX创建一个数学公式文本视图?

3

我是Swift编程的新手,希望使用SwiftUI创建一个应用程序。这就是我想要实现的:

Desired result

也就是说,需要一个文本框,能够实时进行 LaTeX 语法高亮,并通过 mathjax 渲染其内容并在 Web 视图中显示。

我在这个网站和 GitHub 上进行了一些搜索,只发现相关的代码大多是 Objective-C 或 Swift 4.x 的(例如 this),而且没有一个是使用 SwiftUI 进行界面设计的。然而,在我的研究中我找到了一种可能可行的方法。看起来使用 JavaScriptCore 框架可以利用 highlight.js 实现语法高亮(类似于 Highlightr 所做的那样,但它的代码非常复杂)。我对这种方法很有信心,因为如果一个人可以使用 highlight.js 来实现代码高亮,那么类似的,他应该也能使用其他 JavaScript 库如 mathjax.js 来实现其他功能。

很遗憾,由于我对Swift和SwiftUI都很陌生,我不知道从哪里开始。 有人可以给我一些提示吗? (欢迎任何帮助,不一定要使用JavaScriptCore

2个回答

2

这是我的当前解决方案,它使用CodeViewer包进行代码高亮,并使用mathjax.js呈现数学公式。

import SwiftUI
import CodeViewer

struct LaTeXView: View {
    @State private var placeholderString: String = "Insert here"
    @State private var inputText: String = ""
    
    var body: some View {
        VStack {
            //MARK: Code editor
            CodeViewer(
                content: $inputText,
                mode: .latex,
                darkTheme: .solarized_dark,
                lightTheme: .solarized_light,
                isReadOnly: false,
                fontSize: 50
            )
            
            //MARK: for rendering math
            HTMLStringView(htmlContent: """
                <html>
                <head>
                  <meta charset="utf-8">
                  <meta name="viewport" content="width=device-width">
                  <title>MathJax example</title>
                  <script>MathJax = {
                        tex:{
                                inlineMath: [['$', '$'], ['\\(', '\\)']],
                                tags: 'ams'
                            },
                        svg:{
                                fontCache: 'global'
                            }
                        };
                  </script>
                  <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
                  <script id="MathJax-script" async
                          src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
                  </script>
                </head>
                <body>
                <p>
                \(inputText.replacingOccurrences(of: "\n\n", with: "<br>"))
                </p>
                </body>
                </html>
                """
            )
        }
    }
}

struct LaTeXView_Previews: PreviewProvider {
    static var previews: some View {
        LaTeXView()
    }
}

结果如下所示:

结果


2

以下是使用一个优秀的框架RichTextView的可能解决方案:

import RichTextView

struct ContentView : View {
    
    @State var string : String = "In physics, the mass-energy equivalence is stated by the equation [math]$E=mc^2$[/math], discovered in 1905 by Albert Einstein."
    
    var body : some View {
        TextField("Test", text: $string)
            .padding(.vertical, 32)
            .border(Color.red)
        
        TextView(string: $string)
            .padding(.horizontal, 16)
    }
}


struct TextView : UIViewRepresentable {
    
    @Binding var string : String
    
    func makeUIView(context: Context) -> RichTextView {
        let richTextView = RichTextView(
            input: string,
            latexParser: LatexParser(),
            font: UIFont.systemFont(ofSize: UIFont.systemFontSize),
            textColor: UIColor.black,
            frame: CGRect.zero,
            completion: nil
        )
        
        return richTextView
        
    }

   func updateUIView(_ uiView: RichTextView, context: Context) {
        uiView.update(
            input: string,
            latexParser: LatexParser(),
            font: UIFont.systemFont(ofSize: UIFont.systemFontSize),
            textColor: UIColor.black,
            completion: nil
        )
   }
}

你总是要以 [math] 开头,以 [/math] 结尾,但可以使用默认的 Latex。更多信息请参阅它们的文档。


请问如何将 RichTextView 添加到我的项目中?我遇到了这个错误:https://github.com/tophat/RichTextView has no Package.swift manifest - Jinwen
我使用Podfile安装了它。 - davidev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接