Passed complete MTMathListBuilderTest suite.
This commit is contained in:
@@ -98,8 +98,8 @@ public class MTMathAtomFactory {
|
|||||||
"widetilde" : "\u{0303}"
|
"widetilde" : "\u{0303}"
|
||||||
]
|
]
|
||||||
|
|
||||||
var _accentValueToName: [String: String]? = nil
|
static var _accentValueToName: [String: String]? = nil
|
||||||
public var accentValueToName: [String: String] {
|
public static var accentValueToName: [String: String] {
|
||||||
if _accentValueToName == nil {
|
if _accentValueToName == nil {
|
||||||
var output = [String: String]()
|
var output = [String: String]()
|
||||||
|
|
||||||
@@ -113,17 +113,14 @@ public class MTMathAtomFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output[value] = key
|
output[value] = key
|
||||||
}
|
}
|
||||||
|
|
||||||
_accentValueToName = output
|
_accentValueToName = output
|
||||||
}
|
}
|
||||||
|
|
||||||
return _accentValueToName!
|
return _accentValueToName!
|
||||||
}
|
}
|
||||||
|
|
||||||
public var supportedLatexSymbols: [String: MTMathAtom] = [
|
public static var supportedLatexSymbols: [String: MTMathAtom] = [
|
||||||
"square" : MTMathAtomFactory.placeholder(),
|
"square" : MTMathAtomFactory.placeholder(),
|
||||||
|
|
||||||
// Greek characters
|
// Greek characters
|
||||||
@@ -386,14 +383,12 @@ public class MTMathAtomFactory {
|
|||||||
"scriptscriptstyle" : MTMathStyle(style: .scriptOfScript),
|
"scriptscriptstyle" : MTMathStyle(style: .scriptOfScript),
|
||||||
]
|
]
|
||||||
|
|
||||||
var latexSymbolNames = [String]()
|
|
||||||
|
|
||||||
var _textToLatexSymbolName: [String: String]? = nil
|
var _textToLatexSymbolName: [String: String]? = nil
|
||||||
public var textToLatexSymbolName: [String: String] {
|
public var textToLatexSymbolName: [String: String] {
|
||||||
get {
|
get {
|
||||||
if self._textToLatexSymbolName == nil {
|
if self._textToLatexSymbolName == nil {
|
||||||
var output = [String: String]()
|
var output = [String: String]()
|
||||||
for (key, atom) in self.supportedLatexSymbols {
|
for (key, atom) in Self.supportedLatexSymbols {
|
||||||
if atom.nucleus.count == 0 {
|
if atom.nucleus.count == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -423,35 +418,32 @@ public class MTMathAtomFactory {
|
|||||||
public static let sharedInstance = MTMathAtomFactory()
|
public static let sharedInstance = MTMathAtomFactory()
|
||||||
|
|
||||||
static let fontStyles : [String: MTFontStyle] = [
|
static let fontStyles : [String: MTFontStyle] = [
|
||||||
"mathnormal" : (.defaultStyle),
|
"mathnormal" : .defaultStyle,
|
||||||
"mathrm": (.roman),
|
"mathrm": .roman,
|
||||||
"textrm": (.roman),
|
"textrm": .roman,
|
||||||
"rm": (.roman),
|
"rm": .roman,
|
||||||
"mathbf": (.bold),
|
"mathbf": .bold,
|
||||||
"bf": (.bold),
|
"bf": .bold,
|
||||||
"textbf": (.bold),
|
"textbf": .bold,
|
||||||
"mathcal": (.caligraphic),
|
"mathcal": .caligraphic,
|
||||||
"cal": (.caligraphic),
|
"cal": .caligraphic,
|
||||||
"mathtt": (.typewriter),
|
"mathtt": .typewriter,
|
||||||
"texttt": (.typewriter),
|
"texttt": .typewriter,
|
||||||
"mathit": (.italic),
|
"mathit": .italic,
|
||||||
"textit": (.italic),
|
"textit": .italic,
|
||||||
"mit": (.italic),
|
"mit": .italic,
|
||||||
"mathsf": (.sansSerif),
|
"mathsf": .sansSerif,
|
||||||
"textsf": (.sansSerif),
|
"textsf": .sansSerif,
|
||||||
"mathfrak": (.fraktur),
|
"mathfrak": .fraktur,
|
||||||
"frak": (.fraktur),
|
"frak": .fraktur,
|
||||||
"mathbb": (.blackboard),
|
"mathbb": .blackboard,
|
||||||
"mathbfit": (.boldItalic),
|
"mathbfit": .boldItalic,
|
||||||
"bm": (.boldItalic),
|
"bm": .boldItalic,
|
||||||
"text": (.roman),
|
"text": .roman,
|
||||||
]
|
]
|
||||||
|
|
||||||
public static func fontStyleWithName(_ fontName:String) -> MTFontStyle? {
|
public static func fontStyleWithName(_ fontName:String) -> MTFontStyle? {
|
||||||
if let style = fontStyles[fontName] {
|
return fontStyles[fontName]
|
||||||
return style
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func fontNameForStyle(_ fontStyle:MTFontStyle) -> String {
|
public static func fontNameForStyle(_ fontStyle:MTFontStyle) -> String {
|
||||||
@@ -600,13 +592,15 @@ public class MTMathAtomFactory {
|
|||||||
If the latex symbol is unknown this will return nil. This supports LaTeX aliases as well.
|
If the latex symbol is unknown this will return nil. This supports LaTeX aliases as well.
|
||||||
*/
|
*/
|
||||||
public static func atom(forLatexSymbol name: String) -> MTMathAtom? {
|
public static func atom(forLatexSymbol name: String) -> MTMathAtom? {
|
||||||
var _name = name
|
var name = name
|
||||||
|
|
||||||
if let canonicalName = aliases[name] {
|
if let canonicalName = aliases[name] {
|
||||||
_name = canonicalName
|
name = canonicalName
|
||||||
}
|
}
|
||||||
|
|
||||||
if let atom = sharedInstance.supportedLatexSymbols[_name] {
|
if let atom = supportedLatexSymbols[name] {
|
||||||
|
if name == "int" { return MTMathAtomFactory.operatorWithName( "\u{222B}", limits: false) }
|
||||||
|
if name == "sum" { return MTMathAtomFactory.operatorWithName( "\u{2211}", limits: true) }
|
||||||
return atom
|
return atom
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,7 +620,7 @@ public class MTMathAtomFactory {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return Self.sharedInstance.textToLatexSymbolName[atom.nucleus]
|
return sharedInstance.textToLatexSymbolName[atom.nucleus]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Define a latex symbol for rendering. This function allows defining custom symbols that are
|
/** Define a latex symbol for rendering. This function allows defining custom symbols that are
|
||||||
@@ -635,12 +629,12 @@ public class MTMathAtomFactory {
|
|||||||
`[MTMathAtomFactory addLatexSymbol:@"lcm" value:[MTMathAtomFactory operatorWithName:@"lcm" limits: false)]` */
|
`[MTMathAtomFactory addLatexSymbol:@"lcm" value:[MTMathAtomFactory operatorWithName:@"lcm" limits: false)]` */
|
||||||
|
|
||||||
public static func add(latexSymbol name: String, value: MTMathAtom) {
|
public static func add(latexSymbol name: String, value: MTMathAtom) {
|
||||||
Self.sharedInstance.supportedLatexSymbols[name] = value
|
supportedLatexSymbols[name] = value
|
||||||
Self.sharedInstance.textToLatexSymbolName[value.nucleus] = name
|
sharedInstance.textToLatexSymbolName[value.nucleus] = name
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a large opertor for the given name. If limits is true, limits are set up on
|
/** Returns a large opertor for the given name. If limits is true, limits are set up on
|
||||||
the operator and displyed differently. */
|
the operator and displayed differently. */
|
||||||
public static func operatorWithName(_ name: String, limits: Bool) -> MTLargeOperator {
|
public static func operatorWithName(_ name: String, limits: Bool) -> MTLargeOperator {
|
||||||
return MTLargeOperator(value: name, limits: limits)
|
return MTLargeOperator(value: name, limits: limits)
|
||||||
}
|
}
|
||||||
@@ -650,7 +644,7 @@ public class MTMathAtomFactory {
|
|||||||
returns nil. The `innerList` of the returned `MTAccent` is nil.
|
returns nil. The `innerList` of the returned `MTAccent` is nil.
|
||||||
*/
|
*/
|
||||||
public static func accent(withName name: String) -> MTAccent? {
|
public static func accent(withName name: String) -> MTAccent? {
|
||||||
if let accentValue = Self.accents[name] {
|
if let accentValue = accents[name] {
|
||||||
return MTAccent(value: accentValue)
|
return MTAccent(value: accentValue)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -659,7 +653,7 @@ public class MTMathAtomFactory {
|
|||||||
/** Returns the accent name for the given accent. This is the reverse of the above
|
/** Returns the accent name for the given accent. This is the reverse of the above
|
||||||
function. */
|
function. */
|
||||||
public static func accentName(_ accent: MTAccent) -> String? {
|
public static func accentName(_ accent: MTAccent) -> String? {
|
||||||
return Self.sharedInstance.accentValueToName[accent.nucleus]
|
return accentValueToName[accent.nucleus]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a new boundary atom for the given delimiter name. If the delimiter name
|
/** Creates a new boundary atom for the given delimiter name. If the delimiter name
|
||||||
@@ -765,7 +759,7 @@ public class MTMathAtomFactory {
|
|||||||
} else if env == "eqalign" || env == "split" || env == "aligned" {
|
} else if env == "eqalign" || env == "split" || env == "aligned" {
|
||||||
if table.numColumns != 2 {
|
if table.numColumns != 2 {
|
||||||
let message = "\(env) environment can only have 2 columns"
|
let message = "\(env) environment can only have 2 columns"
|
||||||
if error != nil {
|
if error == nil {
|
||||||
error = NSError(domain: MTParseError, code: MTParseErrors.invalidNumColumns.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
error = NSError(domain: MTParseError, code: MTParseErrors.invalidNumColumns.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -789,7 +783,7 @@ public class MTMathAtomFactory {
|
|||||||
} else if env == "displaylines" || env == "gather" {
|
} else if env == "displaylines" || env == "gather" {
|
||||||
if table.numColumns != 1 {
|
if table.numColumns != 1 {
|
||||||
let message = "\(env) environment can only have 1 column"
|
let message = "\(env) environment can only have 1 column"
|
||||||
if error != nil {
|
if error == nil {
|
||||||
error = NSError(domain: MTParseError, code: MTParseErrors.invalidNumColumns.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
error = NSError(domain: MTParseError, code: MTParseErrors.invalidNumColumns.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -804,7 +798,7 @@ public class MTMathAtomFactory {
|
|||||||
} else if env == "eqnarray" {
|
} else if env == "eqnarray" {
|
||||||
if table.numColumns != 3 {
|
if table.numColumns != 3 {
|
||||||
let message = "\(env) environment can only have 3 columns"
|
let message = "\(env) environment can only have 3 columns"
|
||||||
if error != nil {
|
if error == nil {
|
||||||
error = NSError(domain: MTParseError, code: MTParseErrors.invalidNumColumns.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
error = NSError(domain: MTParseError, code: MTParseErrors.invalidNumColumns.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -821,7 +815,7 @@ public class MTMathAtomFactory {
|
|||||||
} else if env == "cases" {
|
} else if env == "cases" {
|
||||||
if table.numColumns != 2 {
|
if table.numColumns != 2 {
|
||||||
let message = "cases environment can only have 2 columns"
|
let message = "cases environment can only have 2 columns"
|
||||||
if error != nil {
|
if error == nil {
|
||||||
error = NSError(domain: MTParseError, code: MTParseErrors.invalidNumColumns.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
error = NSError(domain: MTParseError, code: MTParseErrors.invalidNumColumns.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -852,9 +846,7 @@ public class MTMathAtomFactory {
|
|||||||
return inner
|
return inner
|
||||||
} else {
|
} else {
|
||||||
let message = "Unknown environment \(env)"
|
let message = "Unknown environment \(env)"
|
||||||
if error != nil {
|
error = NSError(domain: MTParseError, code: MTParseErrors.invalidEnv.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
||||||
error = NSError(domain: MTParseError, code: MTParseErrors.invalidNumColumns.rawValue, userInfo: [NSLocalizedDescriptionKey:message])
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,13 +78,29 @@ public enum MTFontStyle:Int {
|
|||||||
boldItalic
|
boldItalic
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MTMathAtom: CustomStringConvertible {
|
public class MTMathAtom: NSObject, NSCopying {
|
||||||
|
|
||||||
public var type: MTMathAtomType
|
public var type: MTMathAtomType
|
||||||
public var subScript: MTMathList?
|
public var subScript: MTMathList?
|
||||||
public var superScript: MTMathList?
|
public var superScript: MTMathList?
|
||||||
|
public var nucleus: String = ""
|
||||||
|
public var childAtoms = [MTMathAtom]() // atoms that fused to create this one
|
||||||
|
public var indexRange = NSRange(location: 0, length: 0) // indexRange in list that this atom tracks:
|
||||||
|
|
||||||
var fontStyle: MTFontStyle = .defaultStyle
|
var fontStyle: MTFontStyle = .defaultStyle
|
||||||
var fusedAtoms: MTMathList?
|
var fusedAtoms: MTMathList?
|
||||||
|
|
||||||
|
public func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let atom = MTMathAtom.atom(withType: type, value: nucleus)
|
||||||
|
atom.type = self.type
|
||||||
|
atom.nucleus = self.nucleus
|
||||||
|
atom.subScript = self.subScript?.copy() as? MTMathList
|
||||||
|
atom.superScript = self.subScript?.copy() as? MTMathList
|
||||||
|
atom.indexRange = self.indexRange
|
||||||
|
atom.fontStyle = self.fontStyle
|
||||||
|
return atom
|
||||||
|
}
|
||||||
|
|
||||||
public static func atom(withType type:MTMathAtomType, value:String) -> MTMathAtom {
|
public static func atom(withType type:MTMathAtomType, value:String) -> MTMathAtom {
|
||||||
switch type {
|
switch type {
|
||||||
case .largeOperator:
|
case .largeOperator:
|
||||||
@@ -118,8 +134,7 @@ public class MTMathAtom: CustomStringConvertible {
|
|||||||
if self.isScriptAllowed() {
|
if self.isScriptAllowed() {
|
||||||
self.superScript = list
|
self.superScript = list
|
||||||
} else {
|
} else {
|
||||||
print("superscripts not allowed for atom \(self.type.rawValue)")
|
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Superscripts not allowed for atom \(self.type.rawValue)").raise()
|
||||||
self.superScript = nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,12 +142,11 @@ public class MTMathAtom: CustomStringConvertible {
|
|||||||
if self.isScriptAllowed() {
|
if self.isScriptAllowed() {
|
||||||
self.subScript = list
|
self.subScript = list
|
||||||
} else {
|
} else {
|
||||||
print("subscripts not allowed for atom \(self.type.rawValue)")
|
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Subscripts not allowed for atom \(self.type.rawValue)").raise()
|
||||||
self.subScript = nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var description: String {
|
public override var description: String {
|
||||||
var string = ""
|
var string = ""
|
||||||
|
|
||||||
string += self.nucleus
|
string += self.nucleus
|
||||||
@@ -146,7 +160,6 @@ public class MTMathAtom: CustomStringConvertible {
|
|||||||
return string
|
return string
|
||||||
}
|
}
|
||||||
|
|
||||||
public var nucleus: String = ""
|
|
||||||
public var finalized: MTMathAtom {
|
public var finalized: MTMathAtom {
|
||||||
let finalized = self
|
let finalized = self
|
||||||
if finalized.superScript != nil {
|
if finalized.superScript != nil {
|
||||||
@@ -158,12 +171,6 @@ public class MTMathAtom: CustomStringConvertible {
|
|||||||
return finalized
|
return finalized
|
||||||
}
|
}
|
||||||
|
|
||||||
// atoms that fused to create this one
|
|
||||||
public var childAtoms = [MTMathAtom]()
|
|
||||||
|
|
||||||
// indexRange in list that this atom tracks:
|
|
||||||
public var indexRange = NSRange(location: 0, length: 0)
|
|
||||||
|
|
||||||
public var string:String {
|
public var string:String {
|
||||||
var str = self.nucleus
|
var str = self.nucleus
|
||||||
if let superScript = self.superScript {
|
if let superScript = self.superScript {
|
||||||
@@ -183,7 +190,7 @@ public class MTMathAtom: CustomStringConvertible {
|
|||||||
self.superScript == nil,
|
self.superScript == nil,
|
||||||
self.type == atom.type
|
self.type == atom.type
|
||||||
else {
|
else {
|
||||||
print("Can't fuse these 2 atom")
|
print("Can't fuse these 2 atoms")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +235,16 @@ public class MTFraction: MTMathAtom {
|
|||||||
public var numerator: MTMathList? = MTMathList()
|
public var numerator: MTMathList? = MTMathList()
|
||||||
public var denominator: MTMathList? = MTMathList()
|
public var denominator: MTMathList? = MTMathList()
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let frac = super.copy(with: zone) as! MTFraction
|
||||||
|
frac.numerator = self.numerator?.copy() as? MTMathList
|
||||||
|
frac.denominator = self.denominator?.copy() as? MTMathList
|
||||||
|
frac.hasRule = self.hasRule
|
||||||
|
frac.leftDelimiter = self.leftDelimiter
|
||||||
|
frac.rightDelimiter = self.rightDelimiter
|
||||||
|
return frac
|
||||||
|
}
|
||||||
|
|
||||||
override public var description: String {
|
override public var description: String {
|
||||||
var string = ""
|
var string = ""
|
||||||
if self.hasRule {
|
if self.hasRule {
|
||||||
@@ -280,6 +297,13 @@ public class MTRadical: MTMathAtom {
|
|||||||
self.init(type: .radical, value: "")
|
self.init(type: .radical, value: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let rad = super.copy(with: zone) as! MTRadical
|
||||||
|
rad.radicand = self.radicand?.copy() as? MTMathList
|
||||||
|
rad.degree = self.degree?.copy() as? MTMathList
|
||||||
|
return rad
|
||||||
|
}
|
||||||
|
|
||||||
override public var description: String {
|
override public var description: String {
|
||||||
var string = "\\sqrt"
|
var string = "\\sqrt"
|
||||||
|
|
||||||
@@ -314,9 +338,16 @@ public class MTRadical: MTMathAtom {
|
|||||||
public class MTLargeOperator: MTMathAtom {
|
public class MTLargeOperator: MTMathAtom {
|
||||||
public var limits: Bool = false
|
public var limits: Bool = false
|
||||||
|
|
||||||
convenience init(value: String, limits: Bool = false) {
|
init(value: String, limits: Bool) {
|
||||||
self.init(type: .largeOperator, value: value)
|
super.init(type: .largeOperator, value: value)
|
||||||
self.limits = limits
|
self.limits = limits
|
||||||
|
//print("Operator \(value) limits:\(limits)")
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let op = super.copy(with: zone) as! MTLargeOperator
|
||||||
|
op.limits = self.limits
|
||||||
|
return op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,6 +370,14 @@ public class MTInner: MTMathAtom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let inner = super.copy(with: zone) as! MTInner
|
||||||
|
inner.innerList = self.innerList?.copy() as? MTMathList
|
||||||
|
inner.leftBoundary = self.leftBoundary?.copy() as? MTMathAtom
|
||||||
|
inner.rightBoundary = self.rightBoundary?.copy() as? MTMathAtom
|
||||||
|
return inner
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
super.init(type: .inner, value: "")
|
super.init(type: .inner, value: "")
|
||||||
}
|
}
|
||||||
@@ -375,9 +414,7 @@ public class MTInner: MTMathAtom {
|
|||||||
|
|
||||||
override public var finalized: MTMathAtom {
|
override public var finalized: MTMathAtom {
|
||||||
let finalized: MTInner = super.finalized as! MTInner
|
let finalized: MTInner = super.finalized as! MTInner
|
||||||
|
|
||||||
finalized.innerList = finalized.innerList?.finalized
|
finalized.innerList = finalized.innerList?.finalized
|
||||||
|
|
||||||
return finalized
|
return finalized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,12 +424,16 @@ public class MTOverLine: MTMathAtom {
|
|||||||
|
|
||||||
override public var finalized: MTMathAtom {
|
override public var finalized: MTMathAtom {
|
||||||
let finalized: MTOverLine = super.finalized as! MTOverLine
|
let finalized: MTOverLine = super.finalized as! MTOverLine
|
||||||
|
|
||||||
finalized.innerList = finalized.innerList?.finalized
|
finalized.innerList = finalized.innerList?.finalized
|
||||||
|
|
||||||
return finalized
|
return finalized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let op = super.copy(with: zone) as! MTOverLine
|
||||||
|
op.innerList = self.innerList?.copy() as? MTMathList
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
convenience init() {
|
convenience init() {
|
||||||
self.init(type: .overline, value: "")
|
self.init(type: .overline, value: "")
|
||||||
}
|
}
|
||||||
@@ -403,12 +444,16 @@ public class MTUnderLine: MTMathAtom {
|
|||||||
|
|
||||||
override public var finalized: MTMathAtom {
|
override public var finalized: MTMathAtom {
|
||||||
let finalized: MTUnderLine = super.finalized as! MTUnderLine
|
let finalized: MTUnderLine = super.finalized as! MTUnderLine
|
||||||
|
|
||||||
finalized.innerList = finalized.innerList?.finalized
|
finalized.innerList = finalized.innerList?.finalized
|
||||||
|
|
||||||
return finalized
|
return finalized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let op = super.copy(with: zone) as! MTUnderLine
|
||||||
|
op.innerList = self.innerList?.copy() as? MTMathList
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
convenience init() {
|
convenience init() {
|
||||||
self.init(type: .underline, value: "")
|
self.init(type: .underline, value: "")
|
||||||
}
|
}
|
||||||
@@ -419,12 +464,16 @@ public class MTAccent: MTMathAtom {
|
|||||||
|
|
||||||
override public var finalized: MTMathAtom {
|
override public var finalized: MTMathAtom {
|
||||||
let finalized: MTAccent = super.finalized as! MTAccent
|
let finalized: MTAccent = super.finalized as! MTAccent
|
||||||
|
|
||||||
finalized.innerList = finalized.innerList?.finalized
|
finalized.innerList = finalized.innerList?.finalized
|
||||||
|
|
||||||
return finalized
|
return finalized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let op = super.copy(with: zone) as! MTAccent
|
||||||
|
op.innerList = self.innerList?.copy() as? MTMathList
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
convenience init(value: String) {
|
convenience init(value: String) {
|
||||||
self.init(type: .accent, value: value)
|
self.init(type: .accent, value: value)
|
||||||
}
|
}
|
||||||
@@ -437,6 +486,13 @@ public class MTMathSpace: MTMathAtom {
|
|||||||
self.init(type: .space, value: "")
|
self.init(type: .space, value: "")
|
||||||
self.space = space
|
self.space = space
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let op = super.copy(with: zone) as! MTMathSpace
|
||||||
|
op.space = self.space
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MTLineStyle {
|
public enum MTLineStyle {
|
||||||
@@ -466,6 +522,12 @@ public class MTMathStyle: MTMathAtom {
|
|||||||
self.init(type: .style, value: "")
|
self.init(type: .style, value: "")
|
||||||
self.style = style
|
self.style = style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let op = super.copy(with: zone) as! MTMathStyle
|
||||||
|
op.style = self.style
|
||||||
|
return op
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MTMathColor: MTMathAtom {
|
public class MTMathColor: MTMathAtom {
|
||||||
@@ -484,6 +546,13 @@ public class MTMathColor: MTMathAtom {
|
|||||||
self.init()
|
self.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let op = super.copy(with: zone) as! MTMathColor
|
||||||
|
op.colorString = self.colorString
|
||||||
|
op.innerList = self.innerList?.copy() as? MTMathList
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
public override var string: String {
|
public override var string: String {
|
||||||
"\\color{\(self.colorString)}{\(self.innerList!.string)}"
|
"\\color{\(self.colorString)}{\(self.innerList!.string)}"
|
||||||
}
|
}
|
||||||
@@ -505,6 +574,13 @@ public class MTMathColorbox: MTMathAtom {
|
|||||||
self.init()
|
self.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let op = super.copy(with: zone) as! MTMathColorbox
|
||||||
|
op.colorString = self.colorString
|
||||||
|
op.innerList = self.innerList?.copy() as? MTMathList
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
public override var string: String {
|
public override var string: String {
|
||||||
"\\colorbox{\(self.colorString)}{\(self.innerList!.string)}"
|
"\\colorbox{\(self.colorString)}{\(self.innerList!.string)}"
|
||||||
}
|
}
|
||||||
@@ -523,8 +599,6 @@ public class MTMathTable: MTMathAtom {
|
|||||||
public var environment: String?
|
public var environment: String?
|
||||||
public var interColumnSpacing: CGFloat = 0
|
public var interColumnSpacing: CGFloat = 0
|
||||||
public var interRowAdditionalSpacing: CGFloat = 0
|
public var interRowAdditionalSpacing: CGFloat = 0
|
||||||
// public var numColumns = 0
|
|
||||||
// public var numRows = 0
|
|
||||||
|
|
||||||
override public var finalized: MTMathAtom {
|
override public var finalized: MTMathAtom {
|
||||||
let finalized: MTMathTable = super.finalized as! MTMathTable
|
let finalized: MTMathTable = super.finalized as! MTMathTable
|
||||||
@@ -543,6 +617,21 @@ public class MTMathTable: MTMathAtom {
|
|||||||
self.environment = environment
|
self.environment = environment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let op = super.copy(with: zone) as! MTMathTable
|
||||||
|
op.interRowAdditionalSpacing = self.interRowAdditionalSpacing
|
||||||
|
op.interColumnSpacing = self.interColumnSpacing
|
||||||
|
op.environment = self.environment
|
||||||
|
var cellCopy = [[MTMathList]]()
|
||||||
|
cellCopy.reserveCapacity(self.cells.count)
|
||||||
|
for row in self.cells {
|
||||||
|
let newRow = [MTMathList](row)
|
||||||
|
cellCopy.append(newRow)
|
||||||
|
}
|
||||||
|
op.cells = cellCopy
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
public func set(cell list: MTMathList, forRow row:Int, column:Int) {
|
public func set(cell list: MTMathList, forRow row:Int, column:Int) {
|
||||||
if self.cells.count <= row {
|
if self.cells.count <= row {
|
||||||
for _ in self.cells.count...row {
|
for _ in self.cells.count...row {
|
||||||
@@ -592,12 +681,19 @@ public class MTMathTable: MTMathAtom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// represent list of math objects
|
// represent list of math objects
|
||||||
extension MTMathList: CustomStringConvertible {
|
extension MTMathList {
|
||||||
public var description: String { self.atoms.description }
|
public override var description: String { self.atoms.description }
|
||||||
public var string: String { self.description }
|
public var string: String { self.description }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MTMathList {
|
public class MTMathList: NSObject, NSCopying {
|
||||||
|
|
||||||
|
public func copy(with zone: NSZone? = nil) -> Any {
|
||||||
|
let list = MTMathList()
|
||||||
|
list.atoms = [MTMathAtom](self.atoms)
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
public var atoms = [MTMathAtom]()
|
public var atoms = [MTMathAtom]()
|
||||||
|
|
||||||
public var finalized: MTMathList {
|
public var finalized: MTMathList {
|
||||||
@@ -658,7 +754,7 @@ public class MTMathList {
|
|||||||
self.atoms.append(atom)
|
self.atoms.append(atom)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init() {
|
public override init() {
|
||||||
self.atoms = []
|
self.atoms = []
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,7 +762,7 @@ public class MTMathList {
|
|||||||
if self.isAtomAllowed(atom) {
|
if self.isAtomAllowed(atom) {
|
||||||
self.atoms.append(atom)
|
self.atoms.append(atom)
|
||||||
} else {
|
} else {
|
||||||
print("error, cannot add atom of type \(atom.type.rawValue) into atomlist")
|
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Cannot add atom of type \(atom.type.rawValue) into mathlist").raise()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,7 +770,7 @@ public class MTMathList {
|
|||||||
if self.isAtomAllowed(atom) {
|
if self.isAtomAllowed(atom) {
|
||||||
self.atoms.insert(atom, at: index)
|
self.atoms.insert(atom, at: index)
|
||||||
} else {
|
} else {
|
||||||
print("error, cannot add atom of type \(atom.type.rawValue) into atomlist")
|
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Cannot add atom of type \(atom.type.rawValue) into mathlist").raise()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,16 +99,16 @@ public class MTMathListBuilder {
|
|||||||
self.spacesAllowed = false
|
self.spacesAllowed = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func build() -> MTMathList? {
|
public func build() -> MTMathList? {
|
||||||
if let list = self.buildInternal(false) {
|
let list = self.buildInternal(false)
|
||||||
if self.hasCharacters {
|
if self.hasCharacters && error == nil {
|
||||||
print("Mismatched braces: \(self.string)")
|
self.setError(.mismatchBraces, message: "Mismatched braces: \(self.string)")
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
} else {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if error != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func build(fromString string: String) -> MTMathList? {
|
public static func build(fromString string: String) -> MTMathList? {
|
||||||
@@ -116,14 +116,12 @@ public class MTMathListBuilder {
|
|||||||
return builder.build()
|
return builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func build(fromString string: String, error:inout NSError) -> MTMathList? {
|
public static func build(fromString string: String, error:inout NSError?) -> MTMathList? {
|
||||||
let builder = MTMathListBuilder(string: string)
|
let builder = MTMathListBuilder(string: string)
|
||||||
let output = builder.build()
|
let output = builder.build()
|
||||||
if builder.error != nil {
|
if builder.error != nil {
|
||||||
error = builder.error!
|
error = builder.error
|
||||||
return nil
|
return nil
|
||||||
} else {
|
|
||||||
error = NSError()
|
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
@@ -213,9 +211,7 @@ public class MTMathListBuilder {
|
|||||||
cell.atoms.removeFirst()
|
cell.atoms.removeFirst()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
str += mathListToString(cell)
|
str += mathListToString(cell)
|
||||||
|
|
||||||
if j < row.count - 1 {
|
if j < row.count - 1 {
|
||||||
str += "&"
|
str += "&"
|
||||||
}
|
}
|
||||||
@@ -224,7 +220,6 @@ public class MTMathListBuilder {
|
|||||||
str += "\\\\ "
|
str += "\\\\ "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if table.environment != nil {
|
if table.environment != nil {
|
||||||
str += "\\end{\(table.environment!)}"
|
str += "\\end{\(table.environment!)}"
|
||||||
}
|
}
|
||||||
@@ -331,11 +326,11 @@ public class MTMathListBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildInternal(_ oneCharOnly: Bool) -> MTMathList? {
|
public func buildInternal(_ oneCharOnly: Bool) -> MTMathList? {
|
||||||
return self.buildInternal(oneCharOnly, stopChar: nil)
|
return self.buildInternal(oneCharOnly, stopChar: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildInternal(_ oneCharOnly: Bool, stopChar stop: Character?) -> MTMathList? {
|
public func buildInternal(_ oneCharOnly: Bool, stopChar stop: Character?) -> MTMathList? {
|
||||||
let list = MTMathList()
|
let list = MTMathList()
|
||||||
assert(!(oneCharOnly && stop != nil), "Cannot set both oneCharOnly and stopChar.")
|
assert(!(oneCharOnly && stop != nil), "Cannot set both oneCharOnly and stopChar.")
|
||||||
var prevAtom: MTMathAtom? = nil
|
var prevAtom: MTMathAtom? = nil
|
||||||
@@ -391,8 +386,7 @@ public class MTMathListBuilder {
|
|||||||
assert(stop == nil, "This should have been handled before")
|
assert(stop == nil, "This should have been handled before")
|
||||||
// We encountered a closing brace when there is no stop set, that means there was no
|
// We encountered a closing brace when there is no stop set, that means there was no
|
||||||
// corresponding opening brace.
|
// corresponding opening brace.
|
||||||
let errorMessage = "Mismatched braces."
|
self.setError(.mismatchBraces, message:"Mismatched braces.")
|
||||||
self.setError(.mismatchBraces, message:errorMessage)
|
|
||||||
return nil
|
return nil
|
||||||
} else if char == "\\" {
|
} else if char == "\\" {
|
||||||
let command = readCommand()
|
let command = readCommand()
|
||||||
@@ -607,16 +601,17 @@ public class MTMathListBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var fractionCommands: [String:[Character]] {
|
||||||
|
[
|
||||||
|
"over": [],
|
||||||
|
"atop" : [],
|
||||||
|
"choose" : [ "(", ")"],
|
||||||
|
"brack" : [ "[", "]"],
|
||||||
|
"brace" : [ "{", "}"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
func stopCommand(_ command: String, list:MTMathList, stopChar:Character?) -> MTMathList? {
|
func stopCommand(_ command: String, list:MTMathList, stopChar:Character?) -> MTMathList? {
|
||||||
var fractionCommands: [String:[Character]] {
|
|
||||||
[
|
|
||||||
"over": [],
|
|
||||||
"atop" : [],
|
|
||||||
"choose" : [ "(", ")"],
|
|
||||||
"brack" : [ "[", "]"],
|
|
||||||
"brace" : [ "{", "}"]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
if command == "right" {
|
if command == "right" {
|
||||||
if currentInnerAtom == nil {
|
if currentInnerAtom == nil {
|
||||||
let errorMessage = "Missing \\left";
|
let errorMessage = "Missing \\left";
|
||||||
@@ -629,7 +624,7 @@ public class MTMathListBuilder {
|
|||||||
}
|
}
|
||||||
// return the list read so far.
|
// return the list read so far.
|
||||||
return list
|
return list
|
||||||
} else if let delims = fractionCommands[command] {
|
} else if let delims = Self.fractionCommands[command] {
|
||||||
var frac:MTFraction! = nil;
|
var frac:MTFraction! = nil;
|
||||||
if command == "over" {
|
if command == "over" {
|
||||||
frac = MTFraction()
|
frac = MTFraction()
|
||||||
@@ -662,11 +657,11 @@ public class MTMathListBuilder {
|
|||||||
if currentEnv == nil {
|
if currentEnv == nil {
|
||||||
let errorMessage = "Missing \\begin";
|
let errorMessage = "Missing \\begin";
|
||||||
self.setError(.missingBegin, message:errorMessage)
|
self.setError(.missingBegin, message:errorMessage)
|
||||||
return nil;
|
return nil
|
||||||
}
|
}
|
||||||
let env = self.readEnvironment()
|
let env = self.readEnvironment()
|
||||||
if env == nil {
|
if env == nil {
|
||||||
return nil;
|
return nil
|
||||||
}
|
}
|
||||||
if env! != currentEnv!.envName {
|
if env! != currentEnv!.envName {
|
||||||
let errorMessage = "Begin environment name \(currentEnv!.envName!) does not match end name: \(env!)"
|
let errorMessage = "Begin environment name \(currentEnv!.envName!) does not match end name: \(env!)"
|
||||||
@@ -683,7 +678,7 @@ public class MTMathListBuilder {
|
|||||||
// Applies the modifier to the atom. Returns true if modifier applied.
|
// Applies the modifier to the atom. Returns true if modifier applied.
|
||||||
func applyModifier(_ modifier:String, atom:MTMathAtom?) -> Bool {
|
func applyModifier(_ modifier:String, atom:MTMathAtom?) -> Bool {
|
||||||
if modifier == "limits" {
|
if modifier == "limits" {
|
||||||
if atom!.type != .largeOperator {
|
if atom?.type != .largeOperator {
|
||||||
let errorMessage = "Limits can only be applied to an operator."
|
let errorMessage = "Limits can only be applied to an operator."
|
||||||
self.setError(.invalidLimits, message:errorMessage)
|
self.setError(.invalidLimits, message:errorMessage)
|
||||||
} else {
|
} else {
|
||||||
@@ -695,14 +690,13 @@ public class MTMathListBuilder {
|
|||||||
if atom?.type != .largeOperator {
|
if atom?.type != .largeOperator {
|
||||||
let errorMessage = "No limits can only be applied to an operator."
|
let errorMessage = "No limits can only be applied to an operator."
|
||||||
self.setError(.invalidLimits, message:errorMessage)
|
self.setError(.invalidLimits, message:errorMessage)
|
||||||
return true
|
|
||||||
} else {
|
} else {
|
||||||
let op = atom as! MTLargeOperator
|
let op = atom as! MTLargeOperator
|
||||||
op.limits = false
|
op.limits = false
|
||||||
}
|
}
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func setError(_ code:MTParseErrors, message:String) {
|
func setError(_ code:MTParseErrors, message:String) {
|
||||||
@@ -795,7 +789,7 @@ public class MTMathListBuilder {
|
|||||||
func readEnvironment() -> String? {
|
func readEnvironment() -> String? {
|
||||||
if !self.expectCharacter("{") {
|
if !self.expectCharacter("{") {
|
||||||
// We didn't find an opening brace, so no env found.
|
// We didn't find an opening brace, so no env found.
|
||||||
print("Missing {")
|
self.setError(.characterNotFound, message: "Missing {")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,7 +798,7 @@ public class MTMathListBuilder {
|
|||||||
|
|
||||||
if !self.expectCharacter("}") {
|
if !self.expectCharacter("}") {
|
||||||
// We didn"t find an closing brace, so invalid format.
|
// We didn"t find an closing brace, so invalid format.
|
||||||
print("Missing {")
|
self.setError(.characterNotFound, message: "Missing }")
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
return env
|
return env
|
||||||
@@ -872,7 +866,7 @@ public class MTMathListBuilder {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var error:NSError?
|
var error:NSError? = self.error
|
||||||
let table = MTMathAtomFactory.table(withEnvironment: currentEnv?.envName, rows: rows, error: &error)
|
let table = MTMathAtomFactory.table(withEnvironment: currentEnv?.envName, rows: rows, error: &error)
|
||||||
if table == nil && self.error == nil {
|
if table == nil && self.error == nil {
|
||||||
self.error = error
|
self.error = error
|
||||||
@@ -892,7 +886,7 @@ public class MTMathListBuilder {
|
|||||||
let boundary = MTMathAtomFactory.boundary(forDelimiter: delim!)
|
let boundary = MTMathAtomFactory.boundary(forDelimiter: delim!)
|
||||||
if boundary == nil {
|
if boundary == nil {
|
||||||
let errorMessage = "Invalid delimiter for \(delimiterType): \(delim!)"
|
let errorMessage = "Invalid delimiter for \(delimiterType): \(delim!)"
|
||||||
self.setError(.missingDelimiter, message:errorMessage)
|
self.setError(.invalidDelimiter, message:errorMessage)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return boundary
|
return boundary
|
||||||
|
|||||||
@@ -71,12 +71,12 @@ class MTMathUILabel : MTView {
|
|||||||
var latex = "" {
|
var latex = "" {
|
||||||
didSet {
|
didSet {
|
||||||
self.error = nil
|
self.error = nil
|
||||||
var error = NSError()
|
var error : NSError? = nil
|
||||||
self.mathList = MTMathListBuilder.build(fromString: latex, error: &error)
|
self.mathList = MTMathListBuilder.build(fromString: latex, error: &error)
|
||||||
if error != NSError() {
|
if error != nil {
|
||||||
self.mathList = nil
|
self.mathList = nil
|
||||||
self.error = error
|
self.error = error
|
||||||
self.errorLabel?.text = error.localizedDescription
|
self.errorLabel?.text = error!.localizedDescription
|
||||||
self.errorLabel?.frame = self.bounds
|
self.errorLabel?.frame = self.bounds
|
||||||
self.errorLabel?.isHidden = !self.displayErrorInline
|
self.errorLabel?.isHidden = !self.displayErrorInline
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -195,9 +195,9 @@ final class SwiftMathRenderTests: XCTestCase {
|
|||||||
let data = getTestData()
|
let data = getTestData()
|
||||||
for testCase in data {
|
for testCase in data {
|
||||||
let str = testCase.build
|
let str = testCase.build
|
||||||
var error = NSError()
|
var error : NSError? = nil
|
||||||
let list = MTMathListBuilder.build(fromString: str, error: &error)
|
let list = MTMathListBuilder.build(fromString: str, error: &error)
|
||||||
XCTAssert(error.code == 0)
|
XCTAssertNil(error)
|
||||||
let desc = "Error for string:\(str)"
|
let desc = "Error for string:\(str)"
|
||||||
let atomTypes = testCase.atomType
|
let atomTypes = testCase.atomType
|
||||||
self.checkAtomTypes(list, types:atomTypes, desc:desc)
|
self.checkAtomTypes(list, types:atomTypes, desc:desc)
|
||||||
@@ -212,9 +212,9 @@ final class SwiftMathRenderTests: XCTestCase {
|
|||||||
let data = getTestDataSuperScript()
|
let data = getTestDataSuperScript()
|
||||||
for testCase in data {
|
for testCase in data {
|
||||||
let str = testCase.build
|
let str = testCase.build
|
||||||
var error = NSError()
|
var error : NSError? = nil
|
||||||
let list = MTMathListBuilder.build(fromString: str, error:&error)
|
let list = MTMathListBuilder.build(fromString: str, error:&error)
|
||||||
XCTAssert(error.code == NSNotFound)
|
XCTAssertNil(error)
|
||||||
let desc = "Error for string:\(str)"
|
let desc = "Error for string:\(str)"
|
||||||
let atomTypes = testCase.atomType
|
let atomTypes = testCase.atomType
|
||||||
checkAtomTypes(list, types:atomTypes, desc:desc)
|
checkAtomTypes(list, types:atomTypes, desc:desc)
|
||||||
@@ -246,9 +246,9 @@ final class SwiftMathRenderTests: XCTestCase {
|
|||||||
let data = getTestDataSubScript()
|
let data = getTestDataSubScript()
|
||||||
for testCase in data {
|
for testCase in data {
|
||||||
let str = testCase.build
|
let str = testCase.build
|
||||||
var error = NSError()
|
var error : NSError? = nil
|
||||||
let list = MTMathListBuilder.build(fromString: str, error:&error)
|
let list = MTMathListBuilder.build(fromString: str, error:&error)
|
||||||
XCTAssert(error.code == NSNotFound)
|
XCTAssertNil(error)
|
||||||
let desc = "Error for string:\(str)"
|
let desc = "Error for string:\(str)"
|
||||||
let atomTypes = testCase.atomType
|
let atomTypes = testCase.atomType
|
||||||
checkAtomTypes(list, types:atomTypes, desc:desc)
|
checkAtomTypes(list, types:atomTypes, desc:desc)
|
||||||
@@ -280,9 +280,9 @@ final class SwiftMathRenderTests: XCTestCase {
|
|||||||
let data = getTestDataSuperSubScript()
|
let data = getTestDataSuperSubScript()
|
||||||
for testCase in data {
|
for testCase in data {
|
||||||
let str = testCase.build
|
let str = testCase.build
|
||||||
var error = NSError()
|
var error : NSError? = nil
|
||||||
let list = MTMathListBuilder.build(fromString: str, error:&error)
|
let list = MTMathListBuilder.build(fromString: str, error:&error)
|
||||||
XCTAssert(error.code == NSNotFound)
|
XCTAssertNil(error)
|
||||||
let desc = "Error for string:\(str)"
|
let desc = "Error for string:\(str)"
|
||||||
let atomTypes = testCase.atomType
|
let atomTypes = testCase.atomType
|
||||||
checkAtomTypes(list, types:atomTypes, desc:desc)
|
checkAtomTypes(list, types:atomTypes, desc:desc)
|
||||||
@@ -508,7 +508,7 @@ final class SwiftMathRenderTests: XCTestCase {
|
|||||||
for testCase in data {
|
for testCase in data {
|
||||||
let str = testCase.build
|
let str = testCase.build
|
||||||
|
|
||||||
var error = NSError()
|
var error : NSError? = nil
|
||||||
let list = MTMathListBuilder.build(fromString: str, error: &error)!
|
let list = MTMathListBuilder.build(fromString: str, error: &error)!
|
||||||
|
|
||||||
XCTAssertNotNil(list, str);
|
XCTAssertNotNil(list, str);
|
||||||
@@ -1149,26 +1149,30 @@ final class SwiftMathRenderTests: XCTestCase {
|
|||||||
let data = getTestDataParseErrors()
|
let data = getTestDataParseErrors()
|
||||||
for testCase in data {
|
for testCase in data {
|
||||||
let str = testCase.0
|
let str = testCase.0
|
||||||
var error = NSError()
|
var error : NSError? = nil
|
||||||
|
if str == "\\begin{displaylines} x & y \\end{displaylines}" {
|
||||||
|
let x = 0
|
||||||
|
}
|
||||||
let list = MTMathListBuilder.build(fromString: str, error:&error)
|
let list = MTMathListBuilder.build(fromString: str, error:&error)
|
||||||
let desc = "Error for string:\(str)"
|
let desc = "Error for string:\(str)"
|
||||||
XCTAssertNil(list, desc)
|
XCTAssertNil(list, desc)
|
||||||
XCTAssertNotNil(error, desc)
|
XCTAssertNotNil(error, desc)
|
||||||
XCTAssertEqual(error.domain, MTParseError, desc)
|
XCTAssertEqual(error!.domain, MTParseError, desc)
|
||||||
|
let code = error!.code
|
||||||
let num = testCase.1
|
let num = testCase.1
|
||||||
let code = num.rawValue
|
XCTAssertEqual(error!.code, num.rawValue, desc)
|
||||||
XCTAssertEqual(error.code, code, desc)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCustom() throws {
|
func testCustom() throws {
|
||||||
let str = "\\lcm(a,b)";
|
let str = "\\lcm(a,b)";
|
||||||
var error = NSError()
|
var error : NSError? = nil
|
||||||
var list = MTMathListBuilder.build(fromString: str, error:&error)
|
var list = MTMathListBuilder.build(fromString: str, error:&error)
|
||||||
XCTAssertNil(list);
|
XCTAssertNil(list)
|
||||||
XCTAssert(error.code == NSNotFound)
|
XCTAssertNotNil(error)
|
||||||
|
|
||||||
MTMathAtomFactory.add(latexSymbol: "lcm", value: MTMathAtomFactory.operatorWithName("lcm", limits:false))
|
MTMathAtomFactory.add(latexSymbol: "lcm", value: MTMathAtomFactory.operatorWithName("lcm", limits:false))
|
||||||
|
error = nil
|
||||||
list = MTMathListBuilder.build(fromString: str, error:&error)
|
list = MTMathListBuilder.build(fromString: str, error:&error)
|
||||||
let atomTypes = [MTMathAtomType.largeOperator, .open, .variable, .punctuation, .variable, .close]
|
let atomTypes = [MTMathAtomType.largeOperator, .open, .variable, .punctuation, .variable, .close]
|
||||||
self.checkAtomTypes(list, types:atomTypes, desc:"Error for lcm")
|
self.checkAtomTypes(list, types:atomTypes, desc:"Error for lcm")
|
||||||
@@ -1319,7 +1323,7 @@ final class SwiftMathRenderTests: XCTestCase {
|
|||||||
XCTAssertEqual((list.atoms.count), 1, desc)
|
XCTAssertEqual((list.atoms.count), 1, desc)
|
||||||
op = list.atoms[0] as! MTLargeOperator
|
op = list.atoms[0] as! MTLargeOperator
|
||||||
XCTAssertEqual(op.type, .largeOperator, desc)
|
XCTAssertEqual(op.type, .largeOperator, desc)
|
||||||
XCTAssertTrue(op.limits);
|
XCTAssertTrue(op.limits)
|
||||||
|
|
||||||
// convert it back to latex
|
// convert it back to latex
|
||||||
latex = MTMathListBuilder.mathListToString(list)
|
latex = MTMathListBuilder.mathListToString(list)
|
||||||
|
|||||||
Reference in New Issue
Block a user