Support for \' \` \^ \~ \= \u \. \" \r \H \v text-mode accents (#802)

* Support for \' \` \^ \~ \= \u \. \" \r \H \v text-mode accents

* bug fix

* Possible Safari fix

* Forbid text accents in math mode

* Switch to noncombining characters for most accents. Revert Safari change.

* Add tests

* Found non-combining diaresis accent too
This commit is contained in:
Erik Demaine
2017-08-23 03:18:33 -04:00
committed by Kevin Barabash
parent e88256b397
commit 201193233e
9 changed files with 64 additions and 4 deletions

View File

@@ -561,6 +561,11 @@ class Parser {
throw new ParseError(
"Can't use function '" + func + "' in text mode",
baseGroup.token);
} else if (this.mode === "math" &&
funcData.allowedInMath === false) {
throw new ParseError(
"Can't use function '" + func + "' in math mode",
baseGroup.token);
}
const args = this.parseArguments(func, funcData);

View File

@@ -1392,7 +1392,7 @@ groupTypes.accent = function(group, options) {
let accentBody;
if (!group.value.isStretchy) {
const accent = buildCommon.makeSymbol(
group.value.label, "Main-Regular", "math", options);
group.value.label, "Main-Regular", group.mode, options);
// Remove the italic correction of the accent, because it only serves to
// shift the accent over to a place we don't want.
accent.italic = 0;
@@ -1401,10 +1401,17 @@ groupTypes.accent = function(group, options) {
// thus shows up much too far to the left. To account for this, we add a
// specific class which shifts the accent over to where we want it.
// TODO(emily): Fix this in a better way, like by changing the font
const vecClass = group.value.label === "\\vec" ? "accent-vec" : null;
// Similarly, text accent \H is a combining character and
// requires a different adjustment.
let accentClass = null;
if (group.value.label === "\\vec") {
accentClass = "accent-vec";
} else if (group.value.label === '\\H') {
accentClass = "accent-hungarian";
}
accentBody = makeSpan(["accent-body", vecClass], [
makeSpan([], [accent])]);
accentBody = makeSpan([], [accent]);
accentBody = makeSpan(["accent-body", accentClass], [accentBody]);
// Shift the accent over by the skew. Note we shift by twice the skew
// because we are centering the accent, so by adding 2*skew to the left,

View File

@@ -92,6 +92,7 @@ function defineFunction(names, props, handler) {
argTypes: props.argTypes,
greediness: (props.greediness === undefined) ? 1 : props.greediness,
allowedInText: !!props.allowedInText,
allowedInMath: props.allowedInMath,
numOptionalArgs: props.numOptionalArgs || 0,
infix: !!props.infix,
handler: handler,
@@ -660,6 +661,27 @@ defineFunction([
};
});
// Text-mode accents
defineFunction([
"\\'", "\\`", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"',
"\\r", "\\H", "\\v",
], {
numArgs: 1,
allowedInText: true,
allowedInMath: false,
}, function(context, args) {
const base = args[0];
return {
type: "accent",
label: context.funcName,
isStretchy: false,
isShifty: true,
value: ordargument(base),
base: base,
};
});
// Horizontal stretchy braces
defineFunction([
"\\overbrace", "\\underbrace",

View File

@@ -616,6 +616,17 @@ defineSymbol(math, main, accent, "\u20d7", "\\vec");
defineSymbol(math, main, accent, "\u02d9", "\\dot");
defineSymbol(math, main, mathord, "\u0131", "\\imath");
defineSymbol(math, main, mathord, "\u0237", "\\jmath");
defineSymbol(text, main, accent, "\u02ca", "\\'"); // acute
defineSymbol(text, main, accent, "\u02cb", "\\`"); // grave
defineSymbol(text, main, accent, "\u02c6", "\\^"); // circumflex
defineSymbol(text, main, accent, "\u02dc", "\\~"); // tilde
defineSymbol(text, main, accent, "\u02c9", "\\="); // macron
defineSymbol(text, main, accent, "\u02d8", "\\u"); // breve
defineSymbol(text, main, accent, "\u02d9", "\\."); // dot above
defineSymbol(text, main, accent, "\u02da", "\\r"); // ring above
defineSymbol(text, main, accent, "\u02c7", "\\v"); // caron
defineSymbol(text, main, accent, "\u00a8", '\\"'); // diaresis
defineSymbol(text, main, accent, "\u030B", "\\H"); // double acute
defineSymbol(text, main, textord, "\u2013", "--");
defineSymbol(text, main, textord, "\u2013", "\\textendash");

View File

@@ -502,6 +502,11 @@
// it left. We center it by shifting it half way right again.
left: 0.326em;
}
.accent-body.accent-hungarian > span {
position: relative;
left: 0.250em; // width of space
}
}
.mtable {

View File

@@ -140,6 +140,11 @@ describe("Parser:", function() {
"Can't use function '\\sqrt' in text mode" +
" at position 7: \\text{\\̲s̲q̲r̲t̲2 is irrational…");
});
it("rejects text-mode-only functions in math mode", function() {
expect("\\'echec").toFailWithParseError(
"Can't use function '\\'' in math mode" +
" at position 1: \\̲'̲echec");
});
});
describe("#parseArguments", function() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -12,6 +12,11 @@
# on the next line. See http://www.yaml.org/ for syntax details.
Accents: \vec{A}\vec{x}\vec x^2\vec{x}_2^2\vec{A}^2\vec{xA}^2
AccentsText: |
\begin{array}{l}
\text{\H{e}}\\
\text{\H{X}}\\
\end{array}
Aligned: |
\begin{aligned}
a &= 1 & b &= 2 \\