New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested Math in Non-Default Text Fix #1111
Nested Math in Non-Default Text Fix #1111
Conversation
One difference with math vs text font commands, is text commands change one aspect of the font (weight, shape, or family). Math commands change all aspects of the font (weight, shape, and family). I'm wondering, probably as a cleanup item, if we'd want to leverage Edit - Opened a separate issue here: #1112 for tracking purposes. Not sure it's a high priority though, nor do I think it should block this. Edit 2 - This PR takes care of this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad to see that the change was relatively straightforward.
src/Options.js
Outdated
withMathMode(): Options { | ||
return this.extend({ | ||
fontFamily: 'mathit', | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this also reset the fontShape and fontWeight?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. I actually thought the same thing until I broke the tests.
it("should render \\textsf{\\textbf{$\\mathrm{\\textsf{A}}$}} with the correct font", function() {
const markup = katex.renderToString("\\textsf{\\textbf{$\\mathrm{\\textsf{A}}$}}");
expect(markup).toContain("<span class=\"mord textsf textbf\">A</span>");
});
Basically when going from text mode, to math mode, then back to text mode, it should retain the font weight/shape from the first time it was in text mode. Hope that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it not also retain the fontFamily
? What happens in this case?
\textsf{\textbf{$\textbf{A}$}}
It feels like we need to:
- store font styles separate for
math
andtext
modes - store which mode we're currently in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch. This means I'll probably resolve #1112 in the process.
src/buildMathML.js
Outdated
@@ -259,7 +259,9 @@ groupTypes.styling = function(group, options) { | |||
}; | |||
|
|||
const newStyle = styleMap[group.value.style]; | |||
const newOptions = options.havingStyle(newStyle); | |||
const newOptions = group.value.mathStart ? | |||
options.havingStyle(newStyle).withMathMode() : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would've expected options.withMathMode()
to be sufficient for this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I follow this. options.withMathMode()
instead of options.havingStyle(newStyle)
?
…TeX into Nested-Math-In-Text-Fix
src/Options.js
Outdated
fontFamily: string | void; | ||
font: string; | ||
oldTextFont: boolean; | ||
fontFamily: string; | ||
fontWeight: string; | ||
fontShape: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking we'd have properties like:
mathFont: string;
textFontFamily: string;
textFontWeight: string;
textFontShape: string;
mode: "text" | "math";
and then the API, would look something like:
.withMathFont(font: string);
.withTextFontFamily(family: string);
.withTextFontWeight(weight: string);
.withTextFontShape(shape: string);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, how would the old text fonts be handled? I.e. \rm \it
. They behave similar to math fonts in that they change all aspects of the font.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot about \rm \it
, but I think we could modify the suggested API in the following way:
.withTextFontFamily(family: string, isOldCommand: boolean = false);
.withTextFontWeight(weight: string, isOldCommand: boolean = false);
.withTextFontShape(shape: string, isOldCommand: boolean = false);
If isOldCommand
is true
, we would reset the other text font properties back to their defaults.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think withTextFontFamily/Weight/Shape
would make sense with old font commands. Old font commands effectively change all 3, not just one. Additionally you'd lose the state when you exit the old font mode (i.e. \textbf{{\it hello} world}
). They behave much more similar to the math commands, which is why I opted to leave the naming conventions generic.
Really wish LaTeX fonts weren't so confusing :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
withTextFontFamily
would look something like:
withTextFontFamily(family: string, isOldCommand: boolean) {
if (isOldCommand) {
this.extend({
fontFamily: fontFamily || this.fontFontFamily,
fontWeight: "",
fontStyle: "",
});
} else {
this.extend({
fontFamily: fontFamily || this.fontFamily,
});
}
};
As for the question of losing state, {\rm hello}
creates a new options
object when processing that group which shouldn't affect the options
object for the \textbf
group.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I'll give this more thought either later today or tomorrow. Thanks for the quick review.
#1073 points out some inconsistencies (compared to LaTeX) in the font size when using |
@edemaine I don't believe this is related. This PR isn't concerned with the font sizing. |
@rrandallcainc friendly ping to see where things are at with this PR. |
@kevinbarabash I expect to get back to this early this week. Thanks for checking in. |
Codecov Report
@@ Coverage Diff @@
## master #1111 +/- ##
==========================================
+ Coverage 79.59% 79.61% +0.02%
==========================================
Files 59 59
Lines 3871 3876 +5
Branches 648 652 +4
==========================================
+ Hits 3081 3086 +5
Misses 656 656
Partials 134 134
Continue to review full report at Codecov.
|
@kevinbarabash I apologize for the delay on this one. This should be ready for another look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The more I look at the implementation of makOrd
the more I don't like it, but this PR was meant to fix a particular problem in the behavior, not refactor all of the code. I would like to tackle that eventually, but not right now.
For now this is looking pretty good. It could use a some comments and/or better typing to reduce confusion between font
, fontFamily
, and fontName
. After that this should be good to go.
@@ -33,7 +33,7 @@ const mainitLetters = [ | |||
const lookupSymbol = function( | |||
value: string, | |||
// TODO(#963): Use a union type for this. | |||
fontFamily: string, | |||
fontName: string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does fontFamily
in Options.js differ from fontName
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A fontFamily
applies to a group of fonts. For example, the SansSerif family can be: regular, bold, or italic. In order to properly lookup the symbol, we need a specific font, not a font family.
// string value. | ||
fontFamily?: string | void; | ||
font?: string; | ||
fontFamily?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does font
differ from fontFamily
? Maybe add some comments and/or be more specific about the types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Font families are a group of fonts, not a specific font. I'll add a comment.
return this.extend({ | ||
fontFamily: fontFamily || this.fontFamily, | ||
font, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we aren't resetting the values of fontFamily
, fontWeight
, etc. I assume that font
takes precedence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. Also, we can't safely reset the values of fontFamily/weight/etc.
Consider the following: \textbf{$\mathsf{\textsf{a}$}
. This should render as a bold, sans-serif "a", but if we reset, we would get a regular sans-serif "a"
@@ -88,7 +88,7 @@ exports[`An implicit group parser within optional groups should work with \\colo | |||
] | |||
`; | |||
|
|||
exports[`An implicit group parser within optional groups should work with sizing commands: \\sqrt[\\small 3]{x} 1`] = ` | |||
exports[`An implicit group parser within optional groups should work with old font functions: \\sqrt[\\tt 3]{x} 1`] = ` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the order of these changed, but the parse trees look the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed a typo, assuming that's why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't mean to suggest that anything needed changing here.
test/screenshotter/ss_data.yaml
Outdated
\begin{matrix} | ||
\text{for $a < b$ and $ c < d $}. \\ | ||
\textsf{for $a < b$ and $ c < d $}. \\ | ||
\textsf{for $a < b \textbf{ and } c < d $} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to have some tests for the behavior of old fonts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update.
@kevinbarabash Updated. Definitely agree that the |
@rrandallcainc glad to see this PR finally merged. Thanks for seeing it through. |
Resolves: