Skip to content

Commit

Permalink
use | to define augmented matrices
Browse files Browse the repository at this point in the history
e.g. ((a,|,b),(c,|,d))
  • Loading branch information
christianp committed Jan 23, 2018
1 parent d579219 commit 2a6f079
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 10 deletions.
76 changes: 67 additions & 9 deletions asciimath2tex.js
Original file line number Diff line number Diff line change
Expand Up @@ -648,14 +648,17 @@ export default class AsciiMathParser {
if(!right) {
return;
}
const contents_tex = contents.rows.map(r=>r.exprs.map(x=>x.tex).join(' & ')).join(' \\\\ ');
return {tex: `\\left ${left.tex} \\begin{matrix} ${contents_tex} \\end{matrix} \\right ${right.tex}`, pos: pos, end: right.end, ttype: 'matrix', rows: contents.rows, left: left, right: right};
const contents_tex = contents.rows.map(r=>r.tex).join(' \\\\ ');
const matrix_tex = contents.is_array ? `\\begin{array}{${contents.column_desc}} ${contents_tex} \\end{array}` : `\\begin{matrix} ${contents_tex} \\end{matrix}`;
return {tex: `\\left ${left.tex} ${matrix_tex} \\right ${right.tex}`, pos: pos, end: right.end, ttype: 'matrix', rows: contents.rows, left: left, right: right};
}

matrix_contents(pos = 0, leftright = false) {
let rows = [];
let end = pos;
let row_length = undefined;
let column_desc = undefined;
let is_array = false;
while(!this.eof(end) && !(leftright ? this.leftright_bracket(end) : this.right_bracket(end))) {
if(rows.length) {
const comma = this.exact(",",end);
Expand All @@ -668,26 +671,81 @@ export default class AsciiMathParser {
if(!lb) {
return;
}
const expr = this.expression_list(lb.end);
if(!expr) {

const cells = [];
const columns = [];
end = lb.end;
while(!this.eof(end)) {
if(cells.length) {
const comma = this.exact(",",end);
if(!comma) {
break;
}
end = comma.end;
}
const cell = this.matrix_cell(end);
if(!cell) {
break;
}
if(cell.ttype=='column') {
columns.push('|');
is_array = true;
if(cell.expr!==null) {
columns.push('r');
cells.push(cell.expr);
}
} else {
columns.push('r');
cells.push(cell);
}
end = cell.end;
}
if(!cells.length) {
return;
}
if(row_length===undefined) {
row_length = expr.exprs.length;
} else if(expr.exprs.length!=row_length) {
row_length = cells.length;
} else if(cells.length!=row_length) {
return;
}
const rb = this.match(/^[)\]]/,expr.end);
const rb = this.match(/^[)\]]/,end);
if(!rb) {
return;
}
rows.push(expr);
const row_column_desc = columns.join('');
if(column_desc===undefined) {
column_desc = row_column_desc;
} else if(row_column_desc!=column_desc) {
return;
}
rows.push({ttype: 'row', tex: cells.map(c=>c.tex).join(' & '), pos: lb.end, end: end, cells: cells});
end = rb.end;
}
if(row_length===undefined || (row_length<=1 && rows.length<=1)) {
return;
}
return {rows: rows, end: end};
return {rows: rows, end: end, column_desc: column_desc, is_array: is_array};
}

matrix_cell(pos = 0) {
const lvert = this.exact('|',pos);
if(lvert) {
const middle = this.expression(lvert.end);
if(middle) {
const rvert = this.exact('|',middle.end);
if(rvert) {
const second = this.expression(rvert.end);
if(second) {
return {tex: `\\left \\lvert ${middle.tex} \\right \\rvert ${second.text}`, pos: lvert.pos, end: second.end, ttype: 'expression', exprs: [middle,second]};
}
} else {
return {ttype: 'column', expr: middle, pos: lvert.pos, end: middle.end};
}
} else {
return {ttype: 'column', expr: null, pos: lvert.pos, end: lvert.end}
}
}
return this.expression(pos);
}

bracketed_expression(pos = 0) {
Expand Down
88 changes: 87 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,81 @@
import AsciiMathParser from './asciimath2tex.js';
window.AsciiMathParser = AsciiMathParser;

class FXParser extends AsciiMathParser {
setup_symbols() {
super.setup_symbols();

this.constants = this.constants.concat([
{"asciimath":"al","tex":"\\alpha"},
{"asciimath":"be","tex":"\\beta"},
{"asciimath":"ga","tex":"\\gamma"},
{"asciimath":"GA","tex":"\\Gamma"},
{"asciimath":"de","tex":"\\delta"},
{"asciimath":"DE","tex":"\\Delta"},
{"asciimath":"ep","tex":"\\epsilon"},
{"asciimath":"va","tex":"\\varepsilon"},
{"asciimath":"ze","tex":"\\zeta"},
{"asciimath":"et","tex":"\\eta"},
{"asciimath":"th","tex":"\\theta"},
{"asciimath":"TH","tex":"\\Theta"},
{"asciimath":"va","tex":"\\vartheta"},
{"asciimath":"io","tex":"\\iota"},
{"asciimath":"ka","tex":"\\kappa"},
{"asciimath":"la","tex":"\\lambda"},
{"asciimath":"LA","tex":"\\Lambda"},
{"asciimath":"mu","tex":"\\mu"},
{"asciimath":"nu","tex":"\\nu"},
{"asciimath":"xi","tex":"\\xi"},
{"asciimath":"XI","tex":"\\Xi"},
{"asciimath":"pi","tex":"\\pi"},
{"asciimath":"PI","tex":"\\Pi"},
{"asciimath":"rh","tex":"\\rho"},
{"asciimath":"si","tex":"\\sigma"},
{"asciimath":"SI","tex":"\\Sigma"},
{"asciimath":"ta","tex":"\\tau"},
{"asciimath":"up","tex":"\\upsilon"},
{"asciimath":"ph","tex":"\\phi"},
{"asciimath":"PH","tex":"\\Phi"},
{"asciimath":"va","tex":"\\varphi"},
{"asciimath":"ch","tex":"\\chi"},
{"asciimath":"ps","tex":"\\psi"},
{"asciimath":"PS","tex":"\\Psi"},
{"asciimath":"om","tex":"\\omega"},
{"asciimath":"OM","tex":"\\Omega"}
]);

this.constants.splice(0,0,...[
{asciimath:"es", tex:"\\emptyset"},
{asciimath:"pd", tex:"\\partial"},
{asciimath:"tf", tex:"\\therefore"},
{asciimath:"te", tex:"\\exists"},
{asciimath:"fa", tex:"\\forall"},
{asciimath:"`", tex:"\\degree"},
{asciimath:"e-", tex:"\\in"},
{asciimath:"xx", tex:"x^2"},
{"asciimath":"cc","tex":"\\mathbb{C}"},
{"asciimath":"nn","tex":"\\mathbb{N}"},
{"asciimath":"qq","tex":"\\mathbb{Q}"},
{"asciimath":"rr","tex":"\\mathbb{R}"},
{"asciimath":"zz","tex":"\\mathbb{Z}"},
]);
this.unary_symbols.push({"asciimath":"sr","tex":"\\sqrt"});
}

scientific(pos = 0) {
const re_science = new RegExp(`^(\\d+(?:${this.decimalsign}\d+)?)E(-?\\d+(?:${this.decimalsign}\\d+)?)`);
const m = this.match(re_science, pos);
if(m) {
return {tex: `${m.match[1]} \\times 10^{${m.match[2]}}`, pos: m.pos, end: m.end};
}
}

number(pos = 0) {
return this.longest([super.number(pos), this.scientific(pos)]);
}
}
window.FXParser = FXParser;

const p = new AsciiMathParser();

const inp = document.getElementById('asciimath');
Expand Down Expand Up @@ -1787,6 +1862,18 @@ const unittests = [
"tex": "\\left \\lbrace \\begin{matrix} 1 & \\quad\\text{if}\\quad & x \\ge 3 \\\\ 2 & \\quad\\text{if}\\quad & x \\gt 3 \\end{matrix} \\right .",
"mathml": "<mrow><mo>{</mo><mtable columnalign=\"left\"><mtr><mtd><mn>1</mn></mtd><mtd><mrow><mspace width=\"1ex\"></mspace><mo>if</mo><mspace width=\"1ex\"></mspace></mrow></mtd><mtd><mi>x</mi><mo>≥</mo><mn>3</mn></mtd></mtr><mtr><mtd><mn>2</mn></mtd><mtd><mrow><mspace width=\"1ex\"></mspace><mo>if</mo><mspace width=\"1ex\"></mspace></mrow></mtd><mtd><mi>x</mi><mo>&gt;</mo><mn>3</mn></mtd></mtr></mtable></mrow>"
},
{
"input": "((a,|b),(c,|d))",
"tex": "\\left ( \\begin{array}{r|r} a & b \\\\ c & d \\end{array} \\right )"
},
{
"input": "((|x|,|2),(3,|4))",
"tex": "\\left ( \\begin{array}{r|r} \\left \\lvert x \\right \\rvert & 2 \\\\ 3 & 4 \\end{array} \\right )"
},
{
"input": "[(x,1,2,|,3),(3,2,1,|,4)]",
"tex": "\\left [ \\begin{array}{rrr|r} x & 1 & 2 & 3 \\\\ 3 & 2 & 1 & 4 \\end{array} \\right ]"
},
{
"input": "int_2^3 3dx",
"tex": "\\int_{2}^{3} 3 dx",
Expand Down Expand Up @@ -2135,4 +2222,3 @@ function run_tests() {
}
const run_tests_button = document.getElementById('run-tests');
run_tests_button.addEventListener('click',run_tests);

0 comments on commit 2a6f079

Please sign in to comment.