From 74422e1462e3703ef9b93e6df63a83f64bd2bd4e Mon Sep 17 00:00:00 2001 From: Ron Kok Date: Sat, 12 May 2018 10:51:14 -0700 Subject: [PATCH] Support \hline (#1306) * Support \hline Support `\hline`. * Fix CSS * Fix lint errors * Add double \hline. Code Cleanup * Reduce width of screenshot test * Add screenshots * Use consumeSpaces, read multiple \hlines * Code cleanup * Update screenshots --- src/environments/array.js | 56 ++++++++++++++++++++ src/katex.less | 6 ++- test/katex-spec.js | 4 ++ test/screenshotter/images/Hline-chrome.png | Bin 0 -> 16247 bytes test/screenshotter/images/Hline-firefox.png | Bin 0 -> 16104 bytes test/screenshotter/ss_data.yaml | 1 + 6 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 test/screenshotter/images/Hline-chrome.png create mode 100644 test/screenshotter/images/Hline-firefox.png diff --git a/src/environments/array.js b/src/environments/array.js index 9462f8fe..61929c23 100644 --- a/src/environments/array.js +++ b/src/environments/array.js @@ -30,8 +30,20 @@ export type ArrayEnvNodeData = { // initialization. body?: ParseNode<*>[][], // List of rows in the (2D) array. rowGaps?: number[], + numHLinesBeforeRow?: number[], }; +function getNumHLines(parser: Parser): number { + let n = 0; + parser.consumeSpaces(); + while (parser.nextToken.text === "\\hline") { + parser.consume(); + n++; + parser.consumeSpaces(); + } + return n; +} + /** * Parse the body of the environment, with rows delimited by \\ and * columns delimited by &, and create a nested list in row-major order @@ -46,6 +58,11 @@ function parseArray( let row = []; const body = [row]; const rowGaps = []; + const numHLinesBeforeRow = []; + + // Test for \hline at the top of the array. + numHLinesBeforeRow.push(getNumHLines(parser)); + while (true) { // eslint-disable-line no-constant-condition let cell = parser.parseExpression(false, undefined); cell = new ParseNode("ordgroup", cell, parser.mode); @@ -76,6 +93,10 @@ function parseArray( throw new ParseError(`Failed to parse function after ${next}`); } rowGaps.push(cr.value.size); + + // check for \hline(s) following the row separator + numHLinesBeforeRow.push(getNumHLines(parser)); + row = []; body.push(row); } else { @@ -85,6 +106,7 @@ function parseArray( } result.body = body; result.rowGaps = rowGaps; + result.numHLinesBeforeRow = numHLinesBeforeRow; return new ParseNode("array", result, parser.mode); } @@ -110,8 +132,10 @@ const htmlBuilder = function(group, options) { let r; let c; const nr = group.value.body.length; + const numHLinesBeforeRow = group.value.numHLinesBeforeRow; let nc = 0; let body = new Array(nr); + const hlinePos = []; // Horizontal spacing const pt = 1 / options.fontMetrics().ptPerEm; @@ -130,6 +154,15 @@ const htmlBuilder = function(group, options) { const arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx let totalHeight = 0; + + // Set a position for \hline(s) at the top of the array, if any. + for (let i = 1; i <= numHLinesBeforeRow[0]; i++) { + if (i > 1) { // The first \hline doesn't add to height. + totalHeight += 0.25; + } + hlinePos.push(totalHeight); + } + for (r = 0; r < group.value.body.length; ++r) { const inrow = group.value.body[r]; let height = arstrutHeight; // \@array adds an \@arstrut @@ -175,6 +208,14 @@ const htmlBuilder = function(group, options) { outrow.pos = totalHeight; totalHeight += depth + gap; // \@yargarraycr body[r] = outrow; + + // Set a position for \hline(s), if any. + for (let i = 1; i <= numHLinesBeforeRow[r + 1]; i++) { + if (i > 1) { // the first \hline doesn't add height + totalHeight += 0.25; + } + hlinePos.push(totalHeight); + } } const offset = totalHeight / 2 + options.fontMetrics().axisHeight; @@ -266,6 +307,21 @@ const htmlBuilder = function(group, options) { } } body = buildCommon.makeSpan(["mtable"], cols); + + // Add \hline(s), if any. + if (hlinePos.length > 0) { + const line = buildCommon.makeLineSpan("hline", options, 0.05); + const vListChildren = [{type: "elem", elem: body, shift: 0}]; + while (hlinePos.length > 0) { + const lineShift = hlinePos.pop() - offset; + vListChildren.push({type: "elem", elem: line, shift: lineShift}); + } + body = buildCommon.makeVList({ + positionType: "individualShift", + children: vListChildren, + }, options); + } + return buildCommon.makeSpan(["mord"], [body], options); }; diff --git a/src/katex.less b/src/katex.less index b199a4d6..b62c5acf 100644 --- a/src/katex.less +++ b/src/katex.less @@ -11,7 +11,8 @@ .mfrac .frac-line, .overline .overline-line, - .underline .underline-line { + .underline .underline-line, + .hline { min-height: 1px; } } @@ -317,7 +318,8 @@ } .overline .overline-line, - .underline .underline-line { + .underline .underline-line, + .hline { display: inline-block; width: 100%; border-bottom-style: solid; diff --git a/test/katex-spec.js b/test/katex-spec.js index adc65f3b..e629dc62 100644 --- a/test/katex-spec.js +++ b/test/katex-spec.js @@ -1356,6 +1356,10 @@ describe("A begin/end parser", function() { expect("\\begin{array}{cc}a&b\\\\c&d\\end{array}").toParse(); }); + it("should parse an environment with hlines", function() { + expect("\\begin{matrix}\\hline a&b\\\\ \\hline c&d\\end{matrix}").toParse(); + }); + it("should error when name is mismatched", function() { expect("\\begin{matrix}a&b\\\\c&d\\end{pmatrix}").toNotParse(); }); diff --git a/test/screenshotter/images/Hline-chrome.png b/test/screenshotter/images/Hline-chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..6a8ebb069d0e6c28b11a7648e38d4b7e58ed29c4 GIT binary patch literal 16247 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 literal 0 HcmV?d00001 diff --git a/test/screenshotter/images/Hline-firefox.png b/test/screenshotter/images/Hline-firefox.png new file mode 100644 index 0000000000000000000000000000000000000000..6f3e56562314a27af39c9a5397fb680dd8ca42da GIT binary patch literal 16104 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 Pw1wT%)z4*}Q$iB}2yk(R literal 0 HcmV?d00001 diff --git a/test/screenshotter/ss_data.yaml b/test/screenshotter/ss_data.yaml index 64d318be..99f18d1a 100644 --- a/test/screenshotter/ss_data.yaml +++ b/test/screenshotter/ss_data.yaml @@ -124,6 +124,7 @@ GroupMacros: \startExp: e^\bgroup \endExp: \egroup tex: \startExp a+b\endExp +Hline: \begin{array}{c|c}\hline \hline \hline a & b \\ \hline \hline \hline c & d \end{array} \quad \frac{\begin{pmatrix} a & b \\ \hline c & d \\ \hline \hline \hline\end{pmatrix}} 2 \quad \begin{bmatrix}\hline a & b \\ \hline c & d \\ \hline e & f \end{bmatrix} HorizontalBraces: \overbrace{\displaystyle{\oint_S{\vec E\cdot\hat n\,\mathrm d a}}}^\text{emf} = \underbrace{\frac{q_{\text{enc}}}{\varepsilon_0}}_{\text{charge}} KaTeX: tex: \KaTeX