[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
@@ -328,6 +328,10 @@ public class MTFraction: MTMathAtom {
|
||||
public var rightDelimiter = ""
|
||||
public var numerator: 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?) {
|
||||
super.init(frac)
|
||||
@@ -338,6 +342,8 @@ public class MTFraction: MTMathAtom {
|
||||
self.hasRule = frac.hasRule
|
||||
self.leftDelimiter = frac.leftDelimiter
|
||||
self.rightDelimiter = frac.rightDelimiter
|
||||
self.isContinuedFraction = frac.isContinuedFraction
|
||||
self.alignment = frac.alignment
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -508,7 +508,14 @@ public struct MTMathListBuilder {
|
||||
}
|
||||
if atom.type == .fraction {
|
||||
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!))}"
|
||||
} else {
|
||||
let command: String
|
||||
@@ -685,6 +692,28 @@ public struct MTMathListBuilder {
|
||||
} else if command == "frac" {
|
||||
// A fraction command has 2 arguments
|
||||
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.denominator = self.buildInternal(true)
|
||||
return frac;
|
||||
@@ -981,6 +1010,27 @@ public struct MTMathListBuilder {
|
||||
return accent
|
||||
} else if command == "frac" {
|
||||
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.denominator = self.buildInternal(true)
|
||||
return frac
|
||||
|
||||
19
Sources/SwiftMath/MathRender/MTTypesetter.swift
Executable file → Normal file
19
Sources/SwiftMath/MathRender/MTTypesetter.swift
Executable file → Normal file
@@ -990,9 +990,22 @@ class MTTypesetter {
|
||||
|
||||
func makeFraction(_ frac:MTFraction?) -> MTDisplay? {
|
||||
// lay out the parts of the fraction
|
||||
let fractionStyle = self.fractionStyle;
|
||||
let numeratorDisplay = MTTypesetter.createLineForMathList(frac!.numerator, font:font, style:fractionStyle(), cramped:false)
|
||||
let denominatorDisplay = MTTypesetter.createLineForMathList(frac!.denominator, font:font, style:fractionStyle(), cramped:true)
|
||||
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;
|
||||
numeratorStyle = fractionStyle()
|
||||
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
|
||||
var numeratorShiftUp = self.numeratorShiftUp(frac!.hasRule)
|
||||
|
||||
Reference in New Issue
Block a user