iosMath icon indicating copy to clipboard operation
iosMath copied to clipboard

How do deal with long LaTeX content?

Open gabrielPeart opened this issue 8 years ago • 14 comments

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.

gabrielPeart avatar Sep 21 '16 20:09 gabrielPeart

Are you saying that the width of the equation is longer than the width of the screen?

In that case you have 2 options:

  1. Reduce the font size.
  2. Split the equation into two parts. You can do this either by using \ or use the aligned or gather environments.

Look towards the end of the examples page on how to do it: https://github.com/kostub/iosMath/blob/master/EXAMPLES.md

kostub avatar Sep 21 '16 23:09 kostub

@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:

  1. 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.
  2. 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?

gabrielPeart avatar Sep 22 '16 19:09 gabrielPeart

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.

kostub avatar Sep 22 '16 19:09 kostub

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;

}

wpstarnice avatar Sep 27 '16 06:09 wpstarnice

Suggestion from @DesmanLead

The ideal interface looks like:

@interface MTMathUILabel : UIView
<...>
@property (nonatomic) BOOL adjustsFontSizeToFit;
<...>
@end

Currently I see the following approaches:

  1. Use binary search or similar approach to find an optimal size over a few iterations.
  2. 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.
  3. (not the clearest one, but robust) Just resize the rendered math to fit label. E.g. render it in a separate CGContext and apply CGAffine​Transform​Scale then.

kostub avatar Mar 31 '17 00:03 kostub

@DesmanLead

Do you know how UILabel figures out the right font size?

kostub avatar Apr 09 '17 06:04 kostub

@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).

DesmanLead avatar Apr 10 '17 16:04 DesmanLead

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 avatar Jul 29 '17 04:07 danielbyon

@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.

gfpoliva avatar Jul 31 '17 15:07 gfpoliva

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 avatar Aug 14 '17 03:08 GauravKanade

@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.

gfpoliva avatar Aug 31 '17 16:08 gfpoliva

@GauravKanade If you figure how to do something like that, could you share with us?

ruofeilyu avatar Jun 03 '18 08:06 ruofeilyu

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?

amer266030 avatar Jun 24 '18 06:06 amer266030

@kostub @gfpoliva @danielbyon @amer266030 @GauravKanade please anyone share me code. How to deal with long Latex content ? i have tried everything but got nothing

iOSharsh avatar Apr 27 '21 09:04 iOSharsh