[MTMathListBuilder][MTTypesetter] add \cfrac support
This commit is contained in:
6
Sources/SwiftMath/MathRender/MTMathList.swift
Executable file → Normal file
6
Sources/SwiftMath/MathRender/MTMathList.swift
Executable file → Normal file
@@ -329,6 +329,10 @@ public class MTFraction: MTMathAtom {
|
|||||||
public var numerator: MTMathList?
|
public var numerator: MTMathList?
|
||||||
public var denominator: MTMathList?
|
public var denominator: MTMathList?
|
||||||
|
|
||||||
|
// Continued fraction properties
|
||||||
|
public var isContinuedFraction: Bool = false
|
||||||
|
public var alignment: String = "c" // "l", "r", "c" for left, right, center
|
||||||
|
|
||||||
init(_ frac: MTFraction?) {
|
init(_ frac: MTFraction?) {
|
||||||
super.init(frac)
|
super.init(frac)
|
||||||
self.type = .fraction
|
self.type = .fraction
|
||||||
@@ -338,6 +342,8 @@ public class MTFraction: MTMathAtom {
|
|||||||
self.hasRule = frac.hasRule
|
self.hasRule = frac.hasRule
|
||||||
self.leftDelimiter = frac.leftDelimiter
|
self.leftDelimiter = frac.leftDelimiter
|
||||||
self.rightDelimiter = frac.rightDelimiter
|
self.rightDelimiter = frac.rightDelimiter
|
||||||
|
self.isContinuedFraction = frac.isContinuedFraction
|
||||||
|
self.alignment = frac.alignment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -508,7 +508,14 @@ public struct MTMathListBuilder {
|
|||||||
}
|
}
|
||||||
if atom.type == .fraction {
|
if atom.type == .fraction {
|
||||||
if let frac = atom as? MTFraction {
|
if let frac = atom as? MTFraction {
|
||||||
if frac.hasRule {
|
if frac.isContinuedFraction {
|
||||||
|
// Generate \cfrac with optional alignment
|
||||||
|
if frac.alignment != "c" {
|
||||||
|
str += "\\cfrac[\(frac.alignment)]{\(mathListToString(frac.numerator!))}{\(mathListToString(frac.denominator!))}"
|
||||||
|
} else {
|
||||||
|
str += "\\cfrac{\(mathListToString(frac.numerator!))}{\(mathListToString(frac.denominator!))}"
|
||||||
|
}
|
||||||
|
} else if frac.hasRule {
|
||||||
str += "\\frac{\(mathListToString(frac.numerator!))}{\(mathListToString(frac.denominator!))}"
|
str += "\\frac{\(mathListToString(frac.numerator!))}{\(mathListToString(frac.denominator!))}"
|
||||||
} else {
|
} else {
|
||||||
let command: String
|
let command: String
|
||||||
@@ -685,6 +692,28 @@ public struct MTMathListBuilder {
|
|||||||
} else if command == "frac" {
|
} else if command == "frac" {
|
||||||
// A fraction command has 2 arguments
|
// A fraction command has 2 arguments
|
||||||
let frac = MTFraction()
|
let frac = MTFraction()
|
||||||
|
frac.numerator = self.buildInternal(true)
|
||||||
|
frac.denominator = self.buildInternal(true)
|
||||||
|
return frac;
|
||||||
|
} else if command == "cfrac" {
|
||||||
|
// A continued fraction command with optional alignment and 2 arguments
|
||||||
|
let frac = MTFraction()
|
||||||
|
frac.isContinuedFraction = true
|
||||||
|
|
||||||
|
// Parse optional alignment parameter [l], [r], [c]
|
||||||
|
skipSpaces()
|
||||||
|
if hasCharacters && string[currentCharIndex] == "[" {
|
||||||
|
_ = getNextCharacter() // consume '['
|
||||||
|
let alignmentChar = getNextCharacter()
|
||||||
|
if alignmentChar == "l" || alignmentChar == "r" || alignmentChar == "c" {
|
||||||
|
frac.alignment = String(alignmentChar)
|
||||||
|
}
|
||||||
|
// Consume closing ']'
|
||||||
|
if hasCharacters && string[currentCharIndex] == "]" {
|
||||||
|
_ = getNextCharacter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
frac.numerator = self.buildInternal(true)
|
frac.numerator = self.buildInternal(true)
|
||||||
frac.denominator = self.buildInternal(true)
|
frac.denominator = self.buildInternal(true)
|
||||||
return frac;
|
return frac;
|
||||||
@@ -981,6 +1010,27 @@ public struct MTMathListBuilder {
|
|||||||
return accent
|
return accent
|
||||||
} else if command == "frac" {
|
} else if command == "frac" {
|
||||||
let frac = MTFraction()
|
let frac = MTFraction()
|
||||||
|
frac.numerator = self.buildInternal(true)
|
||||||
|
frac.denominator = self.buildInternal(true)
|
||||||
|
return frac
|
||||||
|
} else if command == "cfrac" {
|
||||||
|
let frac = MTFraction()
|
||||||
|
frac.isContinuedFraction = true
|
||||||
|
|
||||||
|
// Parse optional alignment parameter [l], [r], [c]
|
||||||
|
skipSpaces()
|
||||||
|
if hasCharacters && string[currentCharIndex] == "[" {
|
||||||
|
_ = getNextCharacter() // consume '['
|
||||||
|
let alignmentChar = getNextCharacter()
|
||||||
|
if alignmentChar == "l" || alignmentChar == "r" || alignmentChar == "c" {
|
||||||
|
frac.alignment = String(alignmentChar)
|
||||||
|
}
|
||||||
|
// Consume closing ']'
|
||||||
|
if hasCharacters && string[currentCharIndex] == "]" {
|
||||||
|
_ = getNextCharacter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
frac.numerator = self.buildInternal(true)
|
frac.numerator = self.buildInternal(true)
|
||||||
frac.denominator = self.buildInternal(true)
|
frac.denominator = self.buildInternal(true)
|
||||||
return frac
|
return frac
|
||||||
|
|||||||
17
Sources/SwiftMath/MathRender/MTTypesetter.swift
Executable file → Normal file
17
Sources/SwiftMath/MathRender/MTTypesetter.swift
Executable file → Normal file
@@ -990,9 +990,22 @@ class MTTypesetter {
|
|||||||
|
|
||||||
func makeFraction(_ frac:MTFraction?) -> MTDisplay? {
|
func makeFraction(_ frac:MTFraction?) -> MTDisplay? {
|
||||||
// lay out the parts of the fraction
|
// lay out the parts of the fraction
|
||||||
|
let numeratorStyle: MTLineStyle
|
||||||
|
let denominatorStyle: MTLineStyle
|
||||||
|
|
||||||
|
if frac!.isContinuedFraction {
|
||||||
|
// Continued fractions always use display style
|
||||||
|
numeratorStyle = .display
|
||||||
|
denominatorStyle = .display
|
||||||
|
} else {
|
||||||
|
// Regular fractions use adaptive style
|
||||||
let fractionStyle = self.fractionStyle;
|
let fractionStyle = self.fractionStyle;
|
||||||
let numeratorDisplay = MTTypesetter.createLineForMathList(frac!.numerator, font:font, style:fractionStyle(), cramped:false)
|
numeratorStyle = fractionStyle()
|
||||||
let denominatorDisplay = MTTypesetter.createLineForMathList(frac!.denominator, font:font, style:fractionStyle(), cramped:true)
|
denominatorStyle = fractionStyle()
|
||||||
|
}
|
||||||
|
|
||||||
|
let numeratorDisplay = MTTypesetter.createLineForMathList(frac!.numerator, font:font, style:numeratorStyle, cramped:false)
|
||||||
|
let denominatorDisplay = MTTypesetter.createLineForMathList(frac!.denominator, font:font, style:denominatorStyle, cramped:true)
|
||||||
|
|
||||||
// determine the location of the numerator
|
// determine the location of the numerator
|
||||||
var numeratorShiftUp = self.numeratorShiftUp(frac!.hasRule)
|
var numeratorShiftUp = self.numeratorShiftUp(frac!.hasRule)
|
||||||
|
|||||||
Reference in New Issue
Block a user