Added color and font styles.
This commit is contained in:
168
Sources/SwiftMathRender/MathRender/MTMathListIndex.swift
Normal file
168
Sources/SwiftMathRender/MathRender/MTMathListIndex.swift
Normal file
@@ -0,0 +1,168 @@
|
||||
//
|
||||
// MTMathListIndex.swift
|
||||
// MathRenderSwift
|
||||
//
|
||||
// Created by Mike Griebling on 2022-12-31.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class MTMathListIndex {
|
||||
|
||||
public enum MTMathListSubIndexType: Int {
|
||||
case none = 0
|
||||
case nucleus
|
||||
case superScript
|
||||
case subScript
|
||||
case numerator
|
||||
case denominator
|
||||
case radicand
|
||||
case degree
|
||||
}
|
||||
|
||||
/// The index of the associated atom.
|
||||
var atomIndex: Int
|
||||
|
||||
/// The type of subindex, e.g. superscript, numerator etc.
|
||||
var subIndexType: MTMathListSubIndexType = .none
|
||||
|
||||
/// The index into the sublist.
|
||||
var subIndex: MTMathListIndex?
|
||||
|
||||
var finalIndex: Int {
|
||||
if self.subIndexType == .none {
|
||||
return self.atomIndex
|
||||
} else {
|
||||
return self.subIndex?.finalIndex ?? 0
|
||||
}
|
||||
}
|
||||
|
||||
func prevIndex() -> MTMathListIndex? {
|
||||
if self.subIndexType == .none {
|
||||
if self.atomIndex > 0 {
|
||||
return MTMathListIndex(level0Index: self.atomIndex - 1)
|
||||
}
|
||||
} else {
|
||||
if let prevSubIndex = self.subIndex?.prevIndex() {
|
||||
return MTMathListIndex(at: self.atomIndex, with: prevSubIndex, type: self.subIndexType)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func nextIndex() -> MTMathListIndex {
|
||||
if self.subIndexType == .none {
|
||||
return MTMathListIndex(level0Index: self.atomIndex + 1)
|
||||
} else if self.subIndexType == .nucleus {
|
||||
return MTMathListIndex(at: self.atomIndex + 1, with: self.subIndex, type: self.subIndexType)
|
||||
} else {
|
||||
return MTMathListIndex(at: self.atomIndex, with: self.subIndex?.nextIndex(), type: self.subIndexType)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this index represents the beginning of a line. Note there may be multiple lines in a MTMathList,
|
||||
* e.g. a superscript or a fraction numerator. This returns true if the innermost subindex points to the beginning of a
|
||||
* line.
|
||||
*/
|
||||
func isBeginningOfLine() -> Bool {
|
||||
return self.finalIndex == 0
|
||||
}
|
||||
|
||||
func isAtSameLevel(with index: MTMathListIndex?) -> Bool {
|
||||
if self.subIndexType != index?.subIndexType {
|
||||
return false
|
||||
} else if self.subIndexType == .none {
|
||||
// No subindexes, they are at the same level.
|
||||
return true
|
||||
} else if (self.atomIndex != index?.atomIndex) {
|
||||
return false
|
||||
} else {
|
||||
return self.subIndex?.isAtSameLevel(with: index?.subIndex) ?? false
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the type of the innermost sub index. */
|
||||
func finalSubIndexType() -> MTMathListSubIndexType {
|
||||
if self.subIndex?.subIndex != nil {
|
||||
return self.subIndex!.finalSubIndexType()
|
||||
} else {
|
||||
return self.subIndexType
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns true if any of the subIndexes of this index have the given type. */
|
||||
func hasSubIndex(ofType type: MTMathListSubIndexType) -> Bool {
|
||||
if self.subIndexType == type {
|
||||
return true
|
||||
} else {
|
||||
return self.subIndex?.hasSubIndex(ofType: type) ?? false
|
||||
}
|
||||
}
|
||||
|
||||
func levelUp(with subIndex: MTMathListIndex?, type: MTMathListSubIndexType) -> MTMathListIndex {
|
||||
if self.subIndexType == .none {
|
||||
return MTMathListIndex(at: self.atomIndex, with: subIndex, type: type)
|
||||
}
|
||||
|
||||
return MTMathListIndex(at: self.atomIndex, with: self.subIndex?.levelUp(with: subIndex, type: type), type: self.subIndexType)
|
||||
}
|
||||
|
||||
func levelDown() -> MTMathListIndex? {
|
||||
if self.subIndexType == .none {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let subIndexDown = self.subIndex?.levelDown() {
|
||||
return MTMathListIndex(at: self.atomIndex, with: subIndexDown, type: self.subIndexType)
|
||||
} else {
|
||||
return MTMathListIndex(level0Index: self.atomIndex)
|
||||
}
|
||||
}
|
||||
|
||||
/** Factory function to create a `MTMathListIndex` with no subindexes.
|
||||
@param index The index of the atom that the `MTMathListIndex` points at.
|
||||
*/
|
||||
public init(level0Index: Int) {
|
||||
self.atomIndex = level0Index
|
||||
}
|
||||
|
||||
public convenience init(at location: Int, with subIndex: MTMathListIndex?, type: MTMathListSubIndexType) {
|
||||
self.init(level0Index: location)
|
||||
self.subIndexType = type
|
||||
self.subIndex = subIndex
|
||||
}
|
||||
}
|
||||
|
||||
extension MTMathListIndex: CustomStringConvertible {
|
||||
public var description: String {
|
||||
if self.subIndex != nil {
|
||||
return "[\(self.atomIndex), \(self.subIndexType.rawValue):\(self.subIndex!)]"
|
||||
}
|
||||
return "[\(self.atomIndex)]"
|
||||
}
|
||||
}
|
||||
|
||||
extension MTMathListIndex: Hashable {
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(self.atomIndex)
|
||||
hasher.combine(self.subIndexType)
|
||||
hasher.combine(self.subIndex)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension MTMathListIndex: Equatable {
|
||||
public static func ==(lhs: MTMathListIndex, rhs: MTMathListIndex) -> Bool {
|
||||
if lhs.atomIndex != rhs.atomIndex || lhs.subIndexType != rhs.subIndexType {
|
||||
return false
|
||||
}
|
||||
|
||||
if rhs.subIndex != nil {
|
||||
return rhs.subIndex == lhs.subIndex
|
||||
} else {
|
||||
return lhs.subIndex == nil
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user