Swift: отображение (LaTeX) математических выражений inline - PullRequest
0 голосов
/ 30 декабря 2018

Я хотел бы отобразить математические термины внутри текста, в частности, во встроенном режиме, то есть внутри предложения.

При использовании LaTeX это будет выглядеть, например, следующим образом: «Учитывая прямоугольный треугольник с катетеромдлина \ (a \) соотв. \ (b \) и гипотенуза длины \ (c \), у нас есть \ [a ^ 2 + b ^ 2 = c ^ 2. \] Этот факт известен как теорема Пифагора. "

Кто-нибудь знает, как этого можно достичь в Swift?

(Я знаю, что этот пример может быть достигнут в Swift без LaTeX-подобных инструментов. Однако выражения в моем умена самом деле более сложный, чем в этом примере, мне нужна мощность LaTeX.)

Оптимальным способом был бы класс, подобный UITextView, который распознает математические разделители \ (, \) и т. д.\ [, \] распознает код LaTeX внутри этих разделителей и соответствующим образом форматирует текст.

В приложении Khan Academy эта проблема, кажется, решается, как показывают снимки экрана в Apple App Store / Google Play Storeinline (LaTeX) math.

Я нашел пакет iosMath, который предоставляет UILabel -подобный класс MTMathUILabel.Поскольку этот класс может отображать только формулы, это, кажется, недостаточно для моей цели, за исключением случаев, когда существует метод, который принимает исходный текст LaTeX, такой как в примере выше, форматирует выражения, такие как \ (a \), в крошечный MTMathUILabel s и устанавливает эти метки между другими текстовыми компонентами.Поскольку я новичок в Swift, я не знаю, можно ли и как этого достичь.Более того, это кажется очень сложным с типографской точки зрения, так как наверняка возникнут трудности с переносами строк.И могут возникнуть проблемы с производительностью, если на экране одновременно присутствует большое количество таких меток?

Можно добиться того, чего я хочу, используя WKWebView и MathJax или KaTeX, что такжевзломать, конечно.Это приводит к другим трудностям, например, если вы хотите установить несколько таких WKWebView с на экране, например, внутри UITableViewCell с.

1 Ответ

0 голосов
/ 30 июля 2019

enter image description here Используя iosMath, мое решение о том, как получить UILabel для встроенного LaTeX, состоит в том, чтобы включить маркеры LATEX и ENDLATEX без пробела.Я заменил все диапазоны изображением MTMathUILabel, переходя от последнего диапазона к первому диапазону, чтобы позиции не были испорчены (это решение позволяет использовать несколько маркеров).Изображение, возвращаемое из моей функции, переворачивается, поэтому я использовал ориентацию .downMirrored, и я изменил его размер, чтобы он соответствовал моему тексту, так что вам может потребоваться немного исправить числа для масштаба 2,5 и значения y для attachment.bounds.

import UIKit
import iosMath

let question = UILabel()
let currentQuestion = "Given a right triangle having catheti of length LATEX(a)ENDLATEX resp. LATEX(b)ENDLATEX and a hypotenuse of length LATEX(c)ENDLATEX, we have LATEX[a^2 + b^2 = c^2]ENDLATEX. This fact is known as the Pythagorean theorem."
question.text = currentQuestion

if (question.text?.contains("LATEX"))! {
        let tempString = question.text!
        let tempMutableString = NSMutableAttributedString(string: tempString)
        let pattern = NSRegularExpression.escapedPattern(for: "LATEX")
        let regex = try? NSRegularExpression(pattern: pattern, options: [])
        if let matches = regex?.matches(in: tempString, options: [], range: NSRange(location: 0, length: tempString.count)) {
               var i = 0
               while i < matches.count {
                    let range1 = matches.reversed()[i+1].range
                    let range2 = matches.reversed()[i].range
                    let finalDistance = range2.location - range1.location + 5
                    let finalRange = NSRange(location: range1.location, length: finalDistance)
                    let startIndex = String.Index(utf16Offset: range1.location + 5, in: tempString)
                    let endIndex = String.Index(utf16Offset: range2.location - 3, in: tempString)
                    let substring = String(tempString[startIndex..<endIndex])
                    var image = UIImage()
                    image = imageWithLabel(string: substring)
                    let flip = UIImage(cgImage: image.cgImage!, scale: 2.5, orientation: .downMirrored)
                    let attachment = NSTextAttachment()
                    attachment.image = flip
                    attachment.bounds = CGRect(x: 0, y: -flip.size.height/2 + 10, width: flip.size.width, height: flip.size.height)
                    let replacement = NSAttributedString(attachment: attachment)
                    tempMutableString.replaceCharacters(in: finalRange, with: replacement)
                    question.attributedText = tempMutableString
                    i += 2
               }
        }
}

func imageWithLabel(string: String) -> UIImage {
        let label = MTMathUILabel()
        label.latex = string
        label.sizeToFit()
        UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0)
        defer { UIGraphicsEndImageContext() }
        label.layer.render(in: UIGraphicsGetCurrentContext()!)
        return UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...