Repository: KaTeX/KaTeX (js)

Issue:
Too strict about accents in math mode
> Before reporting a bug
- [x] Check [common issues](https://katex.org/docs/issues.html).
- [x] Check the bug is reproducible in [the demo](https://katex.org). If not, check KaTeX is up-to-date and installed correctly.
- [x] Search for [existing issues](https://github.com/KaTeX/KaTeX/issues).

**Describe the bug:**
Does not admit `\mathrm{\AA}` even in non-strict. It's a bad idea, but current LaTeX takes it fine.

**(La)TeX code:**
The code of (La)TeX you tried to render:
```latex
\mathrm{\AA}
```

**Expected behavior:**
Should get the Å sign with warnings. LaTeX on overleaf will complain a bit, tell me about how it's hoping that replacing `\accent` with `\mathaccent` will work out, but it does work out.

**Screenshots:**
```
KaTeX parse error: Can't use function '\r' in math mode at position 1: \̲r̲ ̲A
```

**Environment (please complete the following information):**
 - KaTeX Version: 0.13.5
 - Device: Desktop
 - OS: Windows 10
 - Browser: Cr
 - Version: 90

**Additional context:**
Part of #2876. Not something I would normally write, since Unicode feels better and `\text` is a thing.

The parse error is honestly a bit hard to get, since it's complaining about the result of macro expansion.


Pull request:
feat: Allow text-mode accents in math mode, except in strict mode
LaTeX only issues a warning when using e.g. `\r` in math mode.
KaTeX will now do the same with the default `strict` setting of `warn`.

Fixes #2983

Demo:
```latex
\r a\aa\\
\text{\r a\aa}
```

![image](https://user-images.githubusercontent.com/2218736/117880505-316c5380-b276-11eb-9de8-a9a9b9747520.png)

Here's a comparison to QuickLaTeX:
![image](https://user-images.githubusercontent.com/2218736/117880689-67113c80-b276-11eb-98b8-c9e884decfa3.png)


Patch:
diff --git a/src/functions/accent.js b/src/functions/accent.js
index 98dface2..b8b9438a 100644
--- a/src/functions/accent.js
+++ b/src/functions/accent.js
@@ -249,15 +249,22 @@ defineFunction({
     props: {
         numArgs: 1,
         allowedInText: true,
-        allowedInMath: false,
+        allowedInMath: true, // unless in strict mode
         argTypes: ["primitive"],
     },
     handler: (context, args) => {
         const base = args[0];
+        let mode = context.parser.mode;
+
+        if (mode === "math") {
+            context.parser.settings.reportNonstrict("mathVsTextAccents",
+                `LaTeX's accent ${context.funcName} works only in text mode`);
+            mode = "text";
+        }
 
         return {
             type: "accent",
-            mode: context.parser.mode,
+            mode: mode,
             label: context.funcName,
             isStretchy: false,
             isShifty: true,


Test patch:
diff --git a/test/errors-spec.js b/test/errors-spec.js
index f7857a12..4adb1cb9 100644
--- a/test/errors-spec.js
+++ b/test/errors-spec.js
@@ -1,3 +1,5 @@
+import {strictSettings} from "./helpers";
+
 describe("Parser:", function() {
 
     describe("#handleInfixNodes", function() {
@@ -84,10 +86,14 @@ 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");
+        it("rejects text-mode-only functions in math mode", () => {
+            expect`$`.toFailWithParseError(
+                "Can't use function '$' in math mode at position 1: $̲");
+        });
+        it("rejects strict-mode text-mode-only functions in math mode", () => {
+            expect`\'echec`.toFailWithParseError("LaTeX-incompatible input " +
+                "and strict mode is set to 'error': LaTeX's accent \\' works " +
+                "only in text mode [mathVsTextAccents]", strictSettings);
         });
     });
 
diff --git a/test/setup.js b/test/setup.js
index d6ab40f3..e0f10c49 100644
--- a/test/setup.js
+++ b/test/setup.js
@@ -56,8 +56,8 @@ expect.extend({
         return expectKaTeX(expr, settings, Mode.PARSE, this.isNot);
     },
 
-    toFailWithParseError: function(expr, expected = ParseError) {
-        return expectKaTeX(expr, undefined, Mode.PARSE, this.isNot, expected);
+    toFailWithParseError: function(expr, expected = ParseError, settings) {
+        return expectKaTeX(expr, settings, Mode.PARSE, this.isNot, expected);
     },
 
     toBuild(expr, settings) {