iosMath
iosMath copied to clipboard
How do deal with long LaTeX content?
Hi, thanks for sharing this very useful library.
I'm playing around with it and found an edge case where the width of the content is too big and the displayList?.width
is created than the MTMathUILabel
width. Performing sizeThatFits
and layoutSubviews doesn't seem to help.
This is the LaTeX string I'm testing: sin(α) = 0.670, cos(α) = 0.742, sin(β) = 0.742, tan(β) = 1.108
This is my MTMathUILabel setup:
super.init(frame: CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: 140))
self.textAlignment = .Center
self.backgroundColor = UIColor.blueColor()
self.labelMode = .Text
Thanks in advance if you could give me any suggestion.
Are you saying that the width of the equation is longer than the width of the screen?
In that case you have 2 options:
- Reduce the font size.
- Split the equation into two parts. You can do this either by using \ or use the
aligned
orgather
environments.
Look towards the end of the examples page on how to do it: https://github.com/kostub/iosMath/blob/master/EXAMPLES.md
@kostub Yes.
Thanks for answering. I evaluated both cases and the option 1 is a solution. Regarding splitting equation I have no control, since in my use case the user will be able to input any equation.
For the font size reduction I noticed that we have 2 possibilities:
- Identify when the displayList's viewport will change displayList?.width/height and have a closure/delegate to react. Right now I noticed that I got nil as displayList?.width after settings the latex string, but checking it again in a second call gave me the accurate width.
- Add a flag to auto reduce the font size to fit the MTMathUILabel's viewport. When the displayList?.width/height will change, we compare to the MTMathUILabel's and in case of discrepancy we can proportionally decrease/increase the font size. It could be a very nice feature and easy to implement.
What do you think about it?
I had the same problem in my MathEditor, and my solution was to auto shrink the font-size depending on how big the label is.
See the code at: https://github.com/kostub/MathEditor/blob/master/MathEditorExample/MTViewController.m
Basically, I use sizeThatFits
to figure out the size of the label and if that is greater than what I want, I shrink the fontsize. In my case since the label grows gradually as the user types the equation, I can just adjust by a fixed amount.
If you get the whole LaTeX string in one shot there might be some guesswork needed to figure out the right fontsize and then iterate. It will definitely be useful to have this feature be built in. UILabel
does that with adjustsFontSizeToFitWidth:
PS: For your question about getting nil
: The displayList is only calculated when layoutSubviews
is done. To get the size immediately use sizeThatFits
.
i write one class method below to get the approprate frame ,and add mtlabel to scrollview for show +(CGSize)calculateSize:(NSString *)latex{
CGSize size = CGSizeZero;
MTFont* font = [MTFontManager fontManager].defaultFont;
MTLineStyle currentStyle = kMTLineStyleDisplay;
MTMathList * mathList = [MTMathListBuilder buildFromString:latex
error:NULL];
MTMathListDisplay* displayList = nil;
if (mathList) {
displayList = [MTTypesetter createLineForMathList:mathList
font:font
style:currentStyle];
}
CGFloat paddingLeft = 0;
CGFloat paddingRight = 0;
CGFloat paddingTop = 0;
CGFloat paddingBottom = 0;
size.width = displayList.width+paddingLeft+paddingRight;
size.height = displayList.ascent + displayList.descent+paddingTop+paddingBottom;
return size;
}
Suggestion from @DesmanLead
The ideal interface looks like:
@interface MTMathUILabel : UIView
<...>
@property (nonatomic) BOOL adjustsFontSizeToFit;
<...>
@end
Currently I see the following approaches:
- Use binary search or similar approach to find an optimal size over a few iterations.
- Calculate ratio of a desired size to an actual size and use it to calculate the font size. This is fast, but in terms of math rendering the font size does not have a constant correlation with an output size.
- (not the clearest one, but robust) Just resize the rendered math to fit label. E.g. render it in a separate CGContext and apply CGAffineTransformScale then.
@DesmanLead
Do you know how UILabel figures out the right font size?
@kostub
AFAIK, something very similar to (1). minimumFontSize (minimumScaleFactor) can be considered as an initial lower bound for binary search (current font size is an upper bound).
I think the best approach is to calculate an approximate target size using (2) then adjust it using (1).
I'm running into this problem now, where I have long equations, but I can't simply hardcode line breaks, because different devices have different screen widths. Is there any effort to make MTMathUILabel
multi-line compatible, like how UILabel has a numberOfLines
property?
Changing the font size is a mitigation, but doesn't completely solve the issue of long equations eventually getting cut off.
@danielbyon I think MTMathUILabel
was not designed to work like an UILabel
. The main propose of it is to display math equations. If it's a really big equation, you can always wrap up in a scroll view.
I have a similar requirement where my equations are embedded in text. So my code kinda looks like mathView.latex = "\text{some text here} \frac {4}{3} \text{continue the text here}..." But the text goes out of the frame. Is there any way to wrap the text?
Thanks for the help
@GauravKanade If you figure how to do something like that, could you share with us? I would also like to do something like that but unfortunately I don't have any time to do so.
@GauravKanade If you figure how to do something like that, could you share with us?
I found "\parbox" when I was looking up math latex. \text{\parbox{2.5cm}{Insert text here with line breaks}} would this be considered as defining custom commands in the Library as mentioned in the documentation?
@kostub @gfpoliva @danielbyon @amer266030 @GauravKanade please anyone share me code. How to deal with long Latex content ? i have tried everything but got nothing