mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-06 19:58:40 +00:00
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:
committed by
Kevin Barabash
parent
e88256b397
commit
201193233e
@@ -561,6 +561,11 @@ class Parser {
|
|||||||
throw new ParseError(
|
throw new ParseError(
|
||||||
"Can't use function '" + func + "' in text mode",
|
"Can't use function '" + func + "' in text mode",
|
||||||
baseGroup.token);
|
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);
|
const args = this.parseArguments(func, funcData);
|
||||||
|
@@ -1392,7 +1392,7 @@ groupTypes.accent = function(group, options) {
|
|||||||
let accentBody;
|
let accentBody;
|
||||||
if (!group.value.isStretchy) {
|
if (!group.value.isStretchy) {
|
||||||
const accent = buildCommon.makeSymbol(
|
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
|
// Remove the italic correction of the accent, because it only serves to
|
||||||
// shift the accent over to a place we don't want.
|
// shift the accent over to a place we don't want.
|
||||||
accent.italic = 0;
|
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
|
// 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.
|
// 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
|
// 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], [
|
accentBody = makeSpan([], [accent]);
|
||||||
makeSpan([], [accent])]);
|
accentBody = makeSpan(["accent-body", accentClass], [accentBody]);
|
||||||
|
|
||||||
// Shift the accent over by the skew. Note we shift by twice the skew
|
// 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,
|
// because we are centering the accent, so by adding 2*skew to the left,
|
||||||
|
@@ -92,6 +92,7 @@ function defineFunction(names, props, handler) {
|
|||||||
argTypes: props.argTypes,
|
argTypes: props.argTypes,
|
||||||
greediness: (props.greediness === undefined) ? 1 : props.greediness,
|
greediness: (props.greediness === undefined) ? 1 : props.greediness,
|
||||||
allowedInText: !!props.allowedInText,
|
allowedInText: !!props.allowedInText,
|
||||||
|
allowedInMath: props.allowedInMath,
|
||||||
numOptionalArgs: props.numOptionalArgs || 0,
|
numOptionalArgs: props.numOptionalArgs || 0,
|
||||||
infix: !!props.infix,
|
infix: !!props.infix,
|
||||||
handler: handler,
|
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
|
// Horizontal stretchy braces
|
||||||
defineFunction([
|
defineFunction([
|
||||||
"\\overbrace", "\\underbrace",
|
"\\overbrace", "\\underbrace",
|
||||||
|
@@ -616,6 +616,17 @@ defineSymbol(math, main, accent, "\u20d7", "\\vec");
|
|||||||
defineSymbol(math, main, accent, "\u02d9", "\\dot");
|
defineSymbol(math, main, accent, "\u02d9", "\\dot");
|
||||||
defineSymbol(math, main, mathord, "\u0131", "\\imath");
|
defineSymbol(math, main, mathord, "\u0131", "\\imath");
|
||||||
defineSymbol(math, main, mathord, "\u0237", "\\jmath");
|
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", "--");
|
||||||
defineSymbol(text, main, textord, "\u2013", "\\textendash");
|
defineSymbol(text, main, textord, "\u2013", "\\textendash");
|
||||||
|
@@ -502,6 +502,11 @@
|
|||||||
// it left. We center it by shifting it half way right again.
|
// it left. We center it by shifting it half way right again.
|
||||||
left: 0.326em;
|
left: 0.326em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.accent-body.accent-hungarian > span {
|
||||||
|
position: relative;
|
||||||
|
left: 0.250em; // width of space
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mtable {
|
.mtable {
|
||||||
|
@@ -140,6 +140,11 @@ describe("Parser:", function() {
|
|||||||
"Can't use function '\\sqrt' in text mode" +
|
"Can't use function '\\sqrt' in text mode" +
|
||||||
" at position 7: \\text{\\̲s̲q̲r̲t̲2 is irrational…");
|
" 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() {
|
describe("#parseArguments", function() {
|
||||||
|
BIN
test/screenshotter/images/AccentsText-chrome.png
Normal file
BIN
test/screenshotter/images/AccentsText-chrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
BIN
test/screenshotter/images/AccentsText-firefox.png
Normal file
BIN
test/screenshotter/images/AccentsText-firefox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
@@ -12,6 +12,11 @@
|
|||||||
# on the next line. See http://www.yaml.org/ for syntax details.
|
# 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
|
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: |
|
Aligned: |
|
||||||
\begin{aligned}
|
\begin{aligned}
|
||||||
a &= 1 & b &= 2 \\
|
a &= 1 & b &= 2 \\
|
||||||
|
Reference in New Issue
Block a user