Skip to content
This repository has been archived by the owner on Apr 18, 2023. It is now read-only.

Commit

Permalink
fix: multiple latex not rendering (#149)
Browse files Browse the repository at this point in the history
* Good stopping point

* Fixed and cleaned up everything

* Get tests working

* Small fix

* Add example

* update snapshot tests

* Revert "update snapshot tests"

This reverts commit e8a689b.

* added ui

* Update RichTextParser.swift

* Update RichTextViewUITests.swift

* Update RichTextViewUITests.swift

* Update RichTextParser.swift

* snapshots

Co-authored-by: Simon <simon.chau@tophatmonocle.com>
  • Loading branch information
aelkady and Simon223 committed May 20, 2020
1 parent f56b33d commit 40f5c66
Show file tree
Hide file tree
Showing 14 changed files with 294 additions and 188 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ type_body_length:
warning: 300 # warning
error: 400 # error
file_length:
warning: 450
error: 500
function_parameter_count: 6
2 changes: 1 addition & 1 deletion Example/Source/InputOutputModuleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class InputOutputModuleView: UIView, RichTextViewDelegate {
self.outputRichTextView.textViewDelegate = self
self.outputRichTextView.update(
input: text,
attributes: self.attributes
customAdditionalAttributes: self.attributes
)
}

Expand Down
3 changes: 2 additions & 1 deletion Example/Source/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ class ViewController: UIViewController {
InputOutputModuleView(text: "<blockquote>Here is a blockquote</blockquote>"),
InputOutputModuleView(text: "Look [interactive-element id=123]This is an interactive element[/interactive-element] Wow"),
InputOutputModuleView(text: "Look [highlighted-element id=456]This is an highlighted element[/highlighted-element] Wow"),
InputOutputModuleView(text: "Here is more LaTeX [math]A^{}=P^{}\\left(1+\\frac{r}{n}\\right)^{nt}[/math]")
InputOutputModuleView(text: "Here is more LaTeX [math]A^{}=P^{}\\left(1+\\frac{r}{n}\\right)^{nt}[/math]"),
InputOutputModuleView(text: "Multiple Latex and Markdwon: *Yes* [math]_2[/math]TEST[math]_3[/math]")
]
}

Expand Down
1 change: 0 additions & 1 deletion Source/Extensions/NSMutableAttributedStringExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
extension NSAttributedString.Key {
static let customLink = NSAttributedString.Key(rawValue: "customLink")
static let highlight = NSAttributedString.Key(rawValue: "highlight")
static let bullet = NSAttributedString.Key(rawValue: "bullets")
}

extension NSMutableAttributedString {
Expand Down
6 changes: 3 additions & 3 deletions Source/RichTextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class RichTextView: UIView {
textColor: textColor,
latexTextBaselineOffset: latexTextBaselineOffset,
interactiveTextColor: interactiveTextColor,
attributes: customAdditionalAttributes
customAdditionalAttributes: customAdditionalAttributes
)
self.textColor = textColor
self.textViewDelegate = textViewDelegate
Expand All @@ -78,7 +78,7 @@ public class RichTextView: UIView {
textColor: UIColor? = nil,
latexTextBaselineOffset: CGFloat? = nil,
interactiveTextColor: UIColor? = nil,
attributes: [String: [NSAttributedString.Key: Any]]? = nil,
customAdditionalAttributes: [String: [NSAttributedString.Key: Any]]? = nil,
completion: (([ParsingError]?) -> Void)? = nil) {
self.input = input ?? self.input
self.richTextParser = RichTextParser(
Expand All @@ -87,7 +87,7 @@ public class RichTextView: UIView {
textColor: textColor ?? self.textColor,
latexTextBaselineOffset: latexTextBaselineOffset ?? self.richTextParser.latexTextBaselineOffset,
interactiveTextColor: interactiveTextColor ?? self.richTextParser.interactiveTextColor,
attributes: attributes
customAdditionalAttributes: customAdditionalAttributes ?? self.richTextParser.customAdditionalAttributes
)
self.textColor = textColor ?? self.textColor
self.subviews.forEach { $0.removeFromSuperview() }
Expand Down
5 changes: 2 additions & 3 deletions Source/Text Parsing/LatexParserProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public protocol LatexParserProtocol: class {

extension LatexParserProtocol {
public func extractLatex(from input: String, textColor: UIColor, baselineOffset: CGFloat, fontSize: CGFloat, height: CGFloat?) -> NSAttributedString? {

let latexInput = self.extractLatexStringInsideTags(from: input)
var mathImage: UIImage?

Expand Down Expand Up @@ -79,9 +78,9 @@ extension LatexParserProtocol {
}

private func getLatexOffset(fromInput input: String, image: UIImage, fontSize: CGFloat) -> CGFloat {
let defaultSubScriptOffset: CGFloat = 2.66
let defaultSubScriptOffset = RichTextParser.ParserConstants.defaultSubScriptOffset
let imageOffset = max((image.size.height - fontSize)/2, 0)
let subscriptOffset: CGFloat = input.contains("_") ? defaultSubScriptOffset : 0
let subscriptOffset: CGFloat = input.contains(RichTextParser.ParserConstants.latexSubscriptCharacter) ? defaultSubScriptOffset : 0
return max(subscriptOffset, imageOffset)
}
}
Expand Down
402 changes: 247 additions & 155 deletions Source/Text Parsing/RichTextParser.swift

Large diffs are not rendered by default.

Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions UITests/RichTextViewUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ class RichTextViewUITests: QuickSpec {
"""
let richTextView = RichTextView(
input: listHTMLString,
customAdditionalAttributes: ["bullet": [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 15)]],
frame: CGRect(origin: .zero, size: Defaults.size
))
customAdditionalAttributes: ["bullets": [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 15)]],
frame: CGRect(origin: .zero, size: Defaults.size)
)
richTextView.backgroundColor = UIColor.white
self.richTextView = richTextView
self.viewController = UIViewController()
Expand Down Expand Up @@ -201,7 +201,7 @@ class RichTextViewUITests: QuickSpec {
richTextView.backgroundColor = UIColor.white
richTextView.update(
input: "[highlighted-element id=123]Heading[/highlighted-element]",
attributes: ["123": [
customAdditionalAttributes: ["123": [
NSAttributedString.Key.backgroundColor: UIColor.lightGray,
NSAttributedString.Key.underlineStyle: 1]
]
Expand Down
54 changes: 34 additions & 20 deletions UnitTests/Text Parsing/RichTextParserSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ class RichTextParserSpec: QuickSpec {
override func spec() {
describe("RichTextParser") {
beforeEach {
self.richTextParser = RichTextParser(attributes: ["123": [
NSAttributedString.Key.backgroundColor: UIColor.lightGray,
NSAttributedString.Key.underlineStyle: 1]
])
self.richTextParser = RichTextParser()
}
context("Latex Parsing") {
it("succesfully returns an NSAttributedString with an image") {
Expand Down Expand Up @@ -64,6 +61,15 @@ class RichTextParserSpec: QuickSpec {
}
}
context("highlighted Element") {
beforeEach {
self.richTextParser = RichTextParser(
customAdditionalAttributes: ["123": [
NSAttributedString.Key.backgroundColor: UIColor.lightGray,
NSAttributedString.Key.underlineStyle: 1
]]
)

}
it("succesfully returns an NSAttributedString with the highlighted property from a basic highlighted element") {
let output = self.richTextParser.extractHighlightedElement(from: NSAttributedString(string: MarkDownText.highlightedElement))
let attributes: [NSAttributedString.Key: Any] = [
Expand All @@ -87,25 +93,25 @@ class RichTextParserSpec: QuickSpec {
}
context("Rich text to attributed string") {
it("generates a single attributed string with multiple rich text types") {
let regularText = self.richTextParser.getAttributedText(from: MarkDownText.regularText).output
let regularText = self.richTextParser.getRichTextWithErrors(from: MarkDownText.regularText).output
expect(regularText.string.range(of: "Some Text")).toNot(beNil())

let complexHTML = self.richTextParser.getAttributedText(from: MarkDownText.complexHTML).output
let complexHTML = self.richTextParser.getRichTextWithErrors(from: MarkDownText.complexHTML).output
expect(complexHTML.string.range(of: "Message")).toNot(beNil())

let complexLatex = self.richTextParser.getAttributedText(from: MarkDownText.complexLatex).output
let complexLatex = self.richTextParser.getRichTextWithErrors(from: MarkDownText.complexLatex).output
expect(complexLatex.string.range(of: "More Text")).toNot(beNil())
}
it("generates a single attributed string with multiple rich text types on a background thread") {
waitUntil { done in
DispatchQueue.global().async {
let regularText = self.richTextParser.getAttributedText(from: MarkDownText.regularText).output
let regularText = self.richTextParser.getRichTextWithErrors(from: MarkDownText.regularText).output
expect(regularText.string.range(of: "Some Text")).toNot(beNil())

let complexHTML = self.richTextParser.getAttributedText(from: MarkDownText.complexHTML).output
let complexHTML = self.richTextParser.getRichTextWithErrors(from: MarkDownText.complexHTML).output
expect(complexHTML.string.range(of: "Message")).toNot(beNil())

let complexLatex = self.richTextParser.getAttributedText(from: MarkDownText.complexLatex).output
let complexLatex = self.richTextParser.getRichTextWithErrors(from: MarkDownText.complexLatex).output
expect(complexLatex.string.range(of: "More Text")).toNot(beNil())
done()
}
Expand All @@ -117,7 +123,7 @@ class RichTextParserSpec: QuickSpec {
let output = self.richTextParser.getRichDataTypes(from: "Look at this video: youtube[12345]")
expect(output.count).to(equal(2))
expect(output[0]).to(equal(RichDataType.text(
richText: self.richTextParser.getAttributedText(from: "Look at this video: ").output,
richText: self.richTextParser.getRichTextWithErrors(from: "Look at this video: ").output,
font: self.richTextParser.font,
errors: [ParsingError]()
)))
Expand All @@ -127,7 +133,7 @@ class RichTextParserSpec: QuickSpec {
let output = self.richTextParser.getRichDataTypes(from: "Look at this!")
expect(output.count).to(equal(1))
expect(output[0]).to(equal(RichDataType.text(
richText: self.richTextParser.getAttributedText(from: "Look at this!").output,
richText: self.richTextParser.getRichTextWithErrors(from: "Look at this!").output,
font: self.richTextParser.font,
errors: [ParsingError]()
)))
Expand All @@ -141,7 +147,7 @@ class RichTextParserSpec: QuickSpec {
}
context("Strip Code Tags") {
it("Successfully strips code tags from input") {
let output = self.richTextParser.getAttributedText(from: MarkDownText.codeText).output
let output = self.richTextParser.getRichTextWithErrors(from: MarkDownText.codeText).output
expect(output.string).to(equal("print('Hello World')"))
}
}
Expand Down Expand Up @@ -186,13 +192,21 @@ class RichTextParserSpec: QuickSpec {

extension RichDataType: Equatable {
public static func == (lhs: RichDataType, rhs: RichDataType) -> Bool {
switch (lhs, rhs) {
case let (.text(left), .text(right)):
return left.richText == right.richText
case let (.video(left), .video(right)):
return left.tag == right.tag
default:
return false
switch lhs {
case .video(tag: let lhsTag, error: _):
switch rhs {
case .video(tag: let rhsTag, error: _):
return lhsTag == rhsTag
default:
return false
}
case .text(richText: let lhsRichText, font: _, errors: _):
switch rhs {
case .text(richText: let rhsRichText, font: _, errors: _):
return lhsRichText.string == rhsRichText.string
default:
return false
}
}
}
}

0 comments on commit 40f5c66

Please sign in to comment.