diff --git a/src/Parser.js b/src/Parser.js index 67b456da..b23d8c42 100644 --- a/src/Parser.js +++ b/src/Parser.js @@ -951,7 +951,8 @@ export default class Parser { if (!unicodeAccents[accent]) { throw new ParseError(`Unknown accent ' ${accent}'`, nucleus); } - const command = unicodeAccents[accent][this.mode]; + const command = unicodeAccents[accent][this.mode] || + unicodeAccents[accent].text; if (!command) { throw new ParseError( `Accent ${accent} unsupported in ${this.mode} mode`, diff --git a/src/fontMetrics.js b/src/fontMetrics.js index 3e459540..1a4d222f 100644 --- a/src/fontMetrics.js +++ b/src/fontMetrics.js @@ -108,11 +108,9 @@ import metricMap from "./fontMetricsData"; const extraCharacterMap = { // Latin-1 'Å': 'A', - 'Ç': 'C', 'Ð': 'D', 'Þ': 'o', 'å': 'a', - 'ç': 'c', 'ð': 'd', 'þ': 'o', diff --git a/src/functions/accent.js b/src/functions/accent.js index b8b9438a..1eb88d5d 100644 --- a/src/functions/accent.js +++ b/src/functions/accent.js @@ -74,10 +74,14 @@ export const htmlBuilder: HtmlBuilderSupSub<"accent"> = (grp, options) => { // TODO(emily): Find a better way to get the skew } + const accentBelow = group.label === "\\c"; + // calculate the amount of space between the body and the accent - let clearance = Math.min( - body.height, - options.fontMetrics().xHeight); + let clearance = accentBelow + ? body.height + body.depth + : Math.min( + body.height, + options.fontMetrics().xHeight); // Build the accent let accentBody; @@ -100,6 +104,9 @@ export const htmlBuilder: HtmlBuilderSupSub<"accent"> = (grp, options) => { // shift the accent over to a place we don't want. accent.italic = 0; width = accent.width; + if (accentBelow) { + clearance += accent.depth; + } } accentBody = buildCommon.makeSpan(["accent-body"], [accent]); @@ -244,7 +251,7 @@ defineFunction({ type: "accent", names: [ "\\'", "\\`", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"', - "\\r", "\\H", "\\v", "\\textcircled", + "\\c", "\\r", "\\H", "\\v", "\\textcircled", ], props: { numArgs: 1, diff --git a/src/symbols.js b/src/symbols.js index 6d2df4cb..cdef331c 100644 --- a/src/symbols.js +++ b/src/symbols.js @@ -706,6 +706,7 @@ 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, "\u00b8", "\\c"); // cedilla defineSymbol(text, main, accent, "\u02da", "\\r"); // ring above defineSymbol(text, main, accent, "\u02c7", "\\v"); // caron defineSymbol(text, main, accent, "\u00a8", '\\"'); // diaresis @@ -875,7 +876,7 @@ for (let i = 0; i < 10; i++) { // but they are not actually in the font, nor are they supported by the // Unicode accent mechanism, so they fall back to Times font and look ugly. // TODO(edemaine): Fix this. -export const extraLatin = "\u00c7\u00d0\u00de\u00e7\u00fe"; +export const extraLatin = "\u00d0\u00de\u00fe"; for (let i = 0; i < extraLatin.length; i++) { const ch = extraLatin.charAt(i); defineSymbol(math, main, mathord, ch, ch); diff --git a/src/unicodeAccents.js b/src/unicodeAccents.js index 06ff052f..e8f15ce9 100644 --- a/src/unicodeAccents.js +++ b/src/unicodeAccents.js @@ -14,4 +14,5 @@ module.exports = { '\u0307': {text: '\\.', math: '\\dot'}, '\u030a': {text: '\\r', math: '\\mathring'}, '\u030b': {text: '\\H'}, + '\u0327': {text: '\\c'}, }; diff --git a/test/screenshotter/images/Unicode-chrome.png b/test/screenshotter/images/Unicode-chrome.png index b3063b18..734765b6 100644 Binary files a/test/screenshotter/images/Unicode-chrome.png and b/test/screenshotter/images/Unicode-chrome.png differ diff --git a/test/screenshotter/images/Unicode-firefox.png b/test/screenshotter/images/Unicode-firefox.png index 8c8e3416..0ff54ce7 100644 Binary files a/test/screenshotter/images/Unicode-firefox.png and b/test/screenshotter/images/Unicode-firefox.png differ diff --git a/test/screenshotter/images/Unicode-safari.png b/test/screenshotter/images/Unicode-safari.png index 408ac459..21acbc3a 100644 Binary files a/test/screenshotter/images/Unicode-safari.png and b/test/screenshotter/images/Unicode-safari.png differ diff --git a/test/unicode-spec.js b/test/unicode-spec.js index f9737454..2c95e66f 100644 --- a/test/unicode-spec.js +++ b/test/unicode-spec.js @@ -9,6 +9,12 @@ describe("unicode", function() { .toBuild(); }); + it("should build Latin-1 inside \\text{} like accent commands", function() { + expect`\text{ÀÁÂÃÄÅÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåèéêëìíîïñòóôõöùúûüýÿÇç}` + .toParseLike`\text{\`A\'A\^A\~A\"A\r A\`E\'E\^E\"E\`I\'I\^I\"I\~N\`O\'O\^O\~O\"O\`U\'U\^U\"U\'Y\`a\'a\^a\~a\"a\r a\`e\'e\^e\"e\`ı\'ı\^ı\"ı\~n\`o\'o\^o\~o\"o\`u\'u\^u\"u\'y\"y\c C\c c}`; + // TODO(edemaine): A few characters don't have analogs yet. + }); + it("should not parse Latin-1 outside \\text{} with strict", function() { const chars = 'ÀÁÂÃÄÅÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝàáâãäåèéêëìíîïñòóôõöùúûüýÿÇÐÞçþ'; for (const ch of chars) {