mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-05 19:28:39 +00:00
Initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
parser.js
|
||||||
|
node_modules
|
8
Makefile
Normal file
8
Makefile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
FILES=parser.js style.css build.js index.html
|
||||||
|
|
||||||
|
.PHONY: ship
|
||||||
|
ship: parser.js
|
||||||
|
scp $(FILES) prgmr:/var/www/www.rampancylabs.com/parser/
|
||||||
|
|
||||||
|
parser.js: parser.jison
|
||||||
|
./node_modules/.bin/jison parser.jison
|
163
build.js
Normal file
163
build.js
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
var doParse = function(toparse, baseelem) {
|
||||||
|
var makeex = function(ex, base) {
|
||||||
|
for (var i = 0; i < ex.length; i++) {
|
||||||
|
var prev = i > 0 ? ex[i-1] : null;
|
||||||
|
var group = makegroup(ex[i], prev);
|
||||||
|
base.appendChild(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
};
|
||||||
|
|
||||||
|
var makegroup = function(group, prev) {
|
||||||
|
if (group.type === "ord") {
|
||||||
|
var elem = document.createElement("span");
|
||||||
|
elem.className = "mord";
|
||||||
|
elem.appendChild(mathit(group.value));
|
||||||
|
return elem;
|
||||||
|
} else if (group.type === "bin") {
|
||||||
|
var elem = document.createElement("span");
|
||||||
|
if (prev == null || prev.type === "bin" || prev.type === "open") {
|
||||||
|
group.type = "ord";
|
||||||
|
elem.className = "mord";
|
||||||
|
} else {
|
||||||
|
elem.className = "mbin";
|
||||||
|
}
|
||||||
|
elem.appendChild(mathit(group.value));
|
||||||
|
return elem;
|
||||||
|
} else if (group.type === "sup") {
|
||||||
|
var elem = document.createElement("span");
|
||||||
|
elem.className = "mord";
|
||||||
|
makeex(group.value.base, elem);
|
||||||
|
|
||||||
|
var sup = document.createElement("span");
|
||||||
|
sup.className = "msup";
|
||||||
|
makeex(group.value.sup, sup);
|
||||||
|
|
||||||
|
elem.appendChild(sup);
|
||||||
|
|
||||||
|
return elem;
|
||||||
|
} else if (group.type === "sub") {
|
||||||
|
var elem = document.createElement("span");
|
||||||
|
elem.className = "mord";
|
||||||
|
makeex(group.value.base, elem);
|
||||||
|
|
||||||
|
var sub = document.createElement("span");
|
||||||
|
sub.className = "msub";
|
||||||
|
makeex(group.value.sub, sub);
|
||||||
|
|
||||||
|
elem.appendChild(sub);
|
||||||
|
|
||||||
|
return elem;
|
||||||
|
} else if (group.type === "supsub") {
|
||||||
|
var elem = document.createElement("span");
|
||||||
|
elem.className = "mord";
|
||||||
|
makeex(group.value.base, elem);
|
||||||
|
|
||||||
|
var supsub = document.createElement("span");
|
||||||
|
supsub.className = "msupsub";
|
||||||
|
|
||||||
|
var sup = document.createElement("span");
|
||||||
|
sup.className = "msup";
|
||||||
|
makeex(group.value.sup, sup);
|
||||||
|
|
||||||
|
var sub = document.createElement("span");
|
||||||
|
sub.className = "msub";
|
||||||
|
makeex(group.value.sub, sub);
|
||||||
|
|
||||||
|
supsub.appendChild(sup);
|
||||||
|
supsub.appendChild(sub);
|
||||||
|
|
||||||
|
elem.appendChild(supsub);
|
||||||
|
|
||||||
|
return elem;
|
||||||
|
} else if (group.type === "open") {
|
||||||
|
var elem = document.createElement("span");
|
||||||
|
elem.className = "mopen";
|
||||||
|
elem.appendChild(mathit(group.value));
|
||||||
|
return elem;
|
||||||
|
} else if (group.type === "close") {
|
||||||
|
var elem = document.createElement("span");
|
||||||
|
elem.className = "mclose";
|
||||||
|
elem.appendChild(mathit(group.value));
|
||||||
|
return elem;
|
||||||
|
} else if (group.type === "cdot") {
|
||||||
|
var elem = document.createElement("span");
|
||||||
|
elem.className = "mbin";
|
||||||
|
elem.appendChild(textit('\u22C5'));
|
||||||
|
return elem;
|
||||||
|
} else if (group.type === "frac") {
|
||||||
|
var frac = document.createElement("span");
|
||||||
|
frac.className = "mord mfrac";
|
||||||
|
|
||||||
|
var numer = document.createElement("span");
|
||||||
|
numer.className = "mfracnum";
|
||||||
|
makeex(group.value.numer, numer);
|
||||||
|
|
||||||
|
var mid = document.createElement("span");
|
||||||
|
mid.className = "mfracmid";
|
||||||
|
mid.appendChild(document.createElement("span"));
|
||||||
|
|
||||||
|
var denom = document.createElement("span");
|
||||||
|
denom.className = "mfracden";
|
||||||
|
makeex(group.value.denom, denom);
|
||||||
|
|
||||||
|
frac.appendChild(numer);
|
||||||
|
frac.appendChild(mid);
|
||||||
|
frac.appendChild(denom);
|
||||||
|
|
||||||
|
return frac;
|
||||||
|
} else {
|
||||||
|
console.log(group.type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var charLookup = {
|
||||||
|
'*': '\u2217',
|
||||||
|
'-': '\u2212',
|
||||||
|
'cdot': '\u22C5'
|
||||||
|
};
|
||||||
|
|
||||||
|
var textit = function(value) {
|
||||||
|
if (value in charLookup) {
|
||||||
|
value = charLookup[value];
|
||||||
|
}
|
||||||
|
return document.createTextNode(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
var mathit = function(value) {
|
||||||
|
var text = textit(value);
|
||||||
|
|
||||||
|
if (/[a-zA-Z]/.test(value)) {
|
||||||
|
var elem = document.createElement("span");
|
||||||
|
elem.className = "mathit";
|
||||||
|
elem.appendChild(text);
|
||||||
|
return elem;
|
||||||
|
} else {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var tree = parser.parse(toparse);
|
||||||
|
clearNode(baseelem);
|
||||||
|
makeex(tree, baseelem);
|
||||||
|
};
|
||||||
|
|
||||||
|
var clearNode = function(node) {
|
||||||
|
var children = node.childNodes;
|
||||||
|
for (var i = children.length - 1; i >= 0; i--) {
|
||||||
|
console.log(children[i]);
|
||||||
|
node.removeChild(children[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
var input = document.getElementById("input");
|
||||||
|
var math = document.getElementById("math");
|
||||||
|
|
||||||
|
doParse(input.value, math);
|
||||||
|
|
||||||
|
input.oninput = function() {
|
||||||
|
doParse(input.value, math);
|
||||||
|
};
|
||||||
|
};
|
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>MJLite Test</title>
|
||||||
|
<script src="parser.js" type="text/javascript"></script>
|
||||||
|
<script src="build.js" type="text/javascript"></script>
|
||||||
|
<link href="style.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<input type="text" value="2x^2 + 3" id="input" />
|
||||||
|
<div id="math"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
7
package.json
Normal file
7
package.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "mjlite",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"devDependencies": {
|
||||||
|
"jison": "~0.4.6"
|
||||||
|
}
|
||||||
|
}
|
81
parser.jison
Normal file
81
parser.jison
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/* description: Parses end executes mathematical expressions. */
|
||||||
|
|
||||||
|
/* lexical grammar */
|
||||||
|
%lex
|
||||||
|
%%
|
||||||
|
|
||||||
|
\s+ /* skip whitespace */
|
||||||
|
cdot return 'CDOT'
|
||||||
|
frac return 'FRAC'
|
||||||
|
[/a-zA-Z0-9] return 'ORD'
|
||||||
|
[*+-] return 'BIN'
|
||||||
|
\^ return '^'
|
||||||
|
[_] return '_'
|
||||||
|
[{] return '{'
|
||||||
|
[}] return '}'
|
||||||
|
[(] return 'OPEN'
|
||||||
|
[)] return 'CLOSE'
|
||||||
|
[\\] return '\\'
|
||||||
|
<<EOF>> return 'EOF'
|
||||||
|
|
||||||
|
/lex
|
||||||
|
|
||||||
|
/* operator associations and precedence */
|
||||||
|
|
||||||
|
%left '^'
|
||||||
|
%left '_'
|
||||||
|
%left 'ORD'
|
||||||
|
%left 'BIN'
|
||||||
|
%left SUPSUB
|
||||||
|
|
||||||
|
%start expression
|
||||||
|
|
||||||
|
%% /* language grammar */
|
||||||
|
|
||||||
|
expression
|
||||||
|
: ex EOF
|
||||||
|
{return $1;}
|
||||||
|
;
|
||||||
|
|
||||||
|
ex
|
||||||
|
:
|
||||||
|
{$$ = [];}
|
||||||
|
| group ex
|
||||||
|
{$$ = $1.concat($2);}
|
||||||
|
| group '^' group ex
|
||||||
|
{$$ = [{type: 'sup', value: {base: $1, sup: $3}}].concat($4);}
|
||||||
|
| group '_' group ex
|
||||||
|
{$$ = [{type: 'sub', value: {base: $1, sub: $3}}].concat($4);}
|
||||||
|
| group '^' group '_' group ex %prec SUPSUB
|
||||||
|
{$$ = [{type: 'supsub', value: {base: $1, sup: $3, sub: $5}}].concat($6);}
|
||||||
|
| group '_' group '^' group ex %prec SUPSUB
|
||||||
|
{$$ = [{type: 'supsub', value: {base: $1, sup: $5, sub: $3}}].concat($6);}
|
||||||
|
;
|
||||||
|
|
||||||
|
group
|
||||||
|
: atom
|
||||||
|
{$$ = $1;}
|
||||||
|
| '{' ex '}'
|
||||||
|
{$$ = $2;}
|
||||||
|
| '\\' func
|
||||||
|
{$$ = $2;}
|
||||||
|
;
|
||||||
|
|
||||||
|
func
|
||||||
|
: 'CDOT'
|
||||||
|
{$$ = [{type: 'bin', value: yytext}];}
|
||||||
|
| 'FRAC' group group
|
||||||
|
{$$ = [{type: 'frac', value: {numer: $2, denom: $3}}];}
|
||||||
|
;
|
||||||
|
|
||||||
|
atom
|
||||||
|
: 'ORD'
|
||||||
|
{$$ = [{type: 'ord', value: yytext}];}
|
||||||
|
| 'BIN'
|
||||||
|
{$$ = [{type: 'bin', value: yytext}];}
|
||||||
|
| 'OPEN'
|
||||||
|
{$$ = [{type: 'open', value: yytext}];}
|
||||||
|
| 'CLOSE'
|
||||||
|
{$$ = [{type: 'close', value: yytext}];}
|
||||||
|
;
|
||||||
|
|
98
style.css
Normal file
98
style.css
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: MathJax_Main;
|
||||||
|
src: url("http://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Main-Regular.otf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: MathJax_Main;
|
||||||
|
src: url("http://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Main-Italic.otf");
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: MathJax_Math;
|
||||||
|
src: url("http://cdn.mathjax.org/mathjax/latest/fonts/HTML-CSS/TeX/otf/MathJax_Math-Italic.otf");
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
thin space: 1/6 quad
|
||||||
|
medium space: 2/9 quad
|
||||||
|
thick space: 5/18 quad
|
||||||
|
|
||||||
|
things to do:
|
||||||
|
^ _ and styles
|
||||||
|
\sin
|
||||||
|
\sum, \int, \lim
|
||||||
|
\frac
|
||||||
|
\sqrt
|
||||||
|
big parens
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin: 0px;
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#math {
|
||||||
|
font-family: MathJax_Main;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mathit {
|
||||||
|
font: italic 100% MathJax_Math;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mord + .mbin {
|
||||||
|
margin-left: 0.22222em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mbin + .mord {
|
||||||
|
margin-left: 0.22222em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msub {
|
||||||
|
vertical-align: bottom;
|
||||||
|
font-size: 70%;
|
||||||
|
position: relative;
|
||||||
|
top: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msup {
|
||||||
|
position: relative;
|
||||||
|
top: -0.5em;
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msupsub {
|
||||||
|
display: inline-table;
|
||||||
|
table-layout: fixed;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msupsub > .msup, .msupsub > .msub {
|
||||||
|
display: table-row;
|
||||||
|
vertical-align: baseline;
|
||||||
|
line-height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mfrac {
|
||||||
|
display: inline-table;
|
||||||
|
vertical-align: 0.88em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mfracnum, .mfracmid, .mfracden {
|
||||||
|
display: table-row;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mfracmid > span {
|
||||||
|
background: black;
|
||||||
|
display: block;
|
||||||
|
height: 0.05em;
|
||||||
|
min-height: 1px;
|
||||||
|
}
|
Reference in New Issue
Block a user