diff --git a/README.md b/README.md
index e62de4b..7fdd4d5 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@ and include the **module**:
```html
+
```
…the **custom element**:
@@ -38,6 +39,7 @@ and include the **module**:
```html
+
```
#### Usage
diff --git a/docs/index.html b/docs/index.html
index 1cd5717..a366d88 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -230,11 +230,20 @@
Client
>min)
+
+
+ Stylesheet (full; not needed for custom element)
+
…and include the module:
- <script type="module" src="mathup.js"></script>
+ <script type="module" src="mathup.js"></script>
+<link rel="stylesheet" href="mathup.css" />
…the custom element:
@@ -242,7 +251,8 @@ Client
…or the script:
- <script src="mathup.iife.js"></script>
+ <script src="mathup.iife.js"></script>
+<link rel="stylesheet" href="mathup.css" />
diff --git a/package-lock.json b/package-lock.json
index ff50421..87a3a7b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -32,6 +32,7 @@
"jsdom": "^22.1.0",
"prettier": "3.0.3",
"rollup": "^4.3.0",
+ "rollup-plugin-copy": "^3.5.0",
"typescript": "^5.2.2"
}
},
@@ -2241,6 +2242,25 @@
"integrity": "sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw==",
"dev": true
},
+ "node_modules/@types/fs-extra": {
+ "version": "8.1.5",
+ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz",
+ "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+ "dev": true,
+ "dependencies": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
@@ -2253,6 +2273,21 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
+ "node_modules/@types/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "20.14.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
+ "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
+ "dev": true,
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
"node_modules/@ungap/structured-clone": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
@@ -2432,6 +2467,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/array.prototype.findlastindex": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz",
@@ -3099,6 +3143,12 @@
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
+ "node_modules/colorette": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
+ "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==",
+ "dev": true
+ },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -4335,6 +4385,29 @@
"node": ">= 6"
}
},
+ "node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/fs-extra/node_modules/universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
"node_modules/fs-readdir-recursive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
@@ -4575,6 +4648,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
+ },
"node_modules/graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
@@ -5462,6 +5541,15 @@
"node": ">=6"
}
},
+ "node_modules/jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+ "dev": true,
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -6552,6 +6640,59 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/rollup-plugin-copy": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.5.0.tgz",
+ "integrity": "sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==",
+ "dev": true,
+ "dependencies": {
+ "@types/fs-extra": "^8.0.1",
+ "colorette": "^1.1.0",
+ "fs-extra": "^8.1.0",
+ "globby": "10.0.1",
+ "is-plain-object": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.3"
+ }
+ },
+ "node_modules/rollup-plugin-copy/node_modules/globby": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz",
+ "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==",
+ "dev": true,
+ "dependencies": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.0.3",
+ "glob": "^7.1.3",
+ "ignore": "^5.1.1",
+ "merge2": "^1.2.3",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/rollup-plugin-copy/node_modules/is-plain-object": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz",
+ "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup-plugin-copy/node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/rrweb-cssom": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
@@ -7419,6 +7560,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "dev": true
+ },
"node_modules/unicode-canonical-property-names-ecmascript": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
diff --git a/package.json b/package.json
index 6ee233c..a98e8f4 100644
--- a/package.json
+++ b/package.json
@@ -88,6 +88,7 @@
"jsdom": "^22.1.0",
"prettier": "3.0.3",
"rollup": "^4.3.0",
+ "rollup-plugin-copy": "^3.5.0",
"typescript": "^5.2.2"
}
}
diff --git a/rollup.config.js b/rollup.config.js
index 1280a82..63a6374 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -1,5 +1,8 @@
+import path from "node:path";
+
import babel from "@rollup/plugin-babel";
import terser from "@rollup/plugin-terser";
+import copy from "rollup-plugin-copy";
/**
* @typedef {import("rollup").RollupOptions} RollupOptions
@@ -47,10 +50,21 @@ const defaultConfig = {
plugins: [terser()],
},
],
+
plugins: [
babel({
babelHelpers: "runtime",
}),
+
+ copy({
+ targets: [
+ {
+ src: path.resolve("./src/stylesheets/core.css"),
+ dest: path.resolve("dist/"),
+ rename: "mathup.css",
+ },
+ ],
+ }),
],
};
diff --git a/src/compiler/tokenizer/lexemes.js b/src/compiler/tokenizer/lexemes.js
index 3360e7f..1d09b33 100644
--- a/src/compiler/tokenizer/lexemes.js
+++ b/src/compiler/tokenizer/lexemes.js
@@ -82,6 +82,8 @@ export function isPunctOpen(char) {
return PUNCT_CLOSE_RE.test(char);
}
+const FUNCTION_IDENT_ATTRS = { class: "mathup-function-ident" };
+
export const KNOWN_IDENTS = new Map([
["CC", { value: "ℂ" }],
["Delta", { value: "Δ", attrs: { mathvariant: "normal" } }],
@@ -102,25 +104,25 @@ export const KNOWN_IDENTS = new Map([
["alpha", { value: "α" }],
["beta", { value: "β" }],
["chi", { value: "χ" }],
- ["cos", { value: "cos" }],
- ["cosh", { value: "cosh" }],
- ["cot", { value: "cot" }],
- ["csc", { value: "csc" }],
+ ["cos", { value: "cos", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["cosh", { value: "cosh", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["cot", { value: "cot", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["csc", { value: "csc", attrs: { ...FUNCTION_IDENT_ATTRS } }],
["delta", { value: "δ" }],
- ["det", { value: "det" }],
- ["dim", { value: "dim" }],
+ ["det", { value: "det", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["dim", { value: "dim", attrs: { ...FUNCTION_IDENT_ATTRS } }],
["epsilon", { value: "ɛ" }],
["eta", { value: "η" }],
["gamma", { value: "γ" }],
- ["gcd", { value: "gcd" }],
+ ["gcd", { value: "gcd", attrs: { ...FUNCTION_IDENT_ATTRS } }],
["iota", { value: "ι" }],
["kappa", { value: "κ" }],
["lambda", { value: "λ" }],
- ["lcm", { value: "lcm" }],
- ["ln", { value: "ln" }],
- ["log", { value: "log" }],
- ["max", { value: "max" }],
- ["min", { value: "min" }],
+ ["lcm", { value: "lcm", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["ln", { value: "ln", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["log", { value: "log", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["max", { value: "max", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["min", { value: "min", attrs: { ...FUNCTION_IDENT_ATTRS } }],
["mu", { value: "μ" }],
["nu", { value: "ν" }],
["omega", { value: "ω" }],
@@ -130,12 +132,12 @@ export const KNOWN_IDENTS = new Map([
["pi", { value: "π" }],
["psi", { value: "ψ" }],
["rho", { value: "ρ" }],
- ["sec", { value: "sec" }],
+ ["sec", { value: "sec", attrs: { ...FUNCTION_IDENT_ATTRS } }],
["sigma", { value: "σ" }],
- ["sin", { value: "sin" }],
- ["sinh", { value: "sinh" }],
- ["tan", { value: "tan" }],
- ["tanh", { value: "tanh" }],
+ ["sin", { value: "sin", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["sinh", { value: "sinh", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["tan", { value: "tan", attrs: { ...FUNCTION_IDENT_ATTRS } }],
+ ["tanh", { value: "tanh", attrs: { ...FUNCTION_IDENT_ATTRS } }],
["tau", { value: "τ" }],
["theta", { value: "θ" }],
["upsilon", { value: "υ" }],
@@ -148,10 +150,10 @@ export const KNOWN_OPS = new Map([
["!=", { value: "≠" }],
["!==", { value: "≢" }],
["!in", { value: "∉" }],
- [".$", { value: "\u2061" }],
- [".*", { value: "\u2062" }],
- [".+", { value: "\u2064" }],
- [".,", { value: "\u2063" }],
+ [".$", { value: "\u2061", attrs: { class: "mathup-function-application" } }],
+ [".*", { value: "\u2062", attrs: { class: "mathup-invisible-times" } }],
+ [".+", { value: "\u2064", attrs: { class: "mathup-invisible-add" } }],
+ [".,", { value: "\u2063", attrs: { class: "mathup-invisible-separator" } }],
["'", { value: "′", attrs: { lspace: 0, rspace: 0 } }],
["''", { value: "″", attrs: { lspace: 0, rspace: 0 } }],
["'''", { value: "‴", attrs: { lspace: 0, rspace: 0 } }],
@@ -318,6 +320,9 @@ export const KNOWN_PREFIX = new Map([
// Roots
["root", { name: "root", arity: 2 }],
["sqrt", { name: "sqrt" }],
+
+ // Enclose
+ ["cancel", { name: "row", attrs: { class: "mathup-enclose-cancel" } }],
]);
export const KNOWN_COMMANDS = new Map([
@@ -356,7 +361,4 @@ export const KNOWN_COMMANDS = new Map([
["bg.red", { name: "background", value: "red" }],
["bg.white", { name: "background", value: "white" }],
["bg.yellow", { name: "background", value: "yellow" }],
-
- // Enclose
- ["cancel", { name: "enclose", value: "updiagonalstrike" }],
]);
diff --git a/src/compiler/transformer/transforms/styles.js b/src/compiler/transformer/transforms/styles.js
index 41e5cdb..b4735c0 100644
--- a/src/compiler/transformer/transforms/styles.js
+++ b/src/compiler/transformer/transforms/styles.js
@@ -1,8 +1,5 @@
/** @typedef {import("../index.js").Tag} Tag */
-const UP_DIAGONAL_STROKE_BACKGROUND =
- "linear-gradient(to bottom right, transparent calc(50% - 0.1ex), currentColor calc(50% - 0.05ex), currentColor calc(50% + 0.05ex), transparent calc(50% + 0.1ex))";
-
/**
* @param {string} name
* @param {string} value
@@ -26,15 +23,9 @@ export function applyStyles(styles, tag) {
const combinedStyles = new Map();
for (const [name, value] of styles) {
- if (
- name === "background" ||
- (name === "enclose" && value === "updiagonalstrike")
- ) {
+ if (name === "background") {
const currentValue = combinedStyles.get("background");
- const backgroundValue =
- name === "background"
- ? withCustomProperty(name, value)
- : UP_DIAGONAL_STROKE_BACKGROUND;
+ const backgroundValue = withCustomProperty(name, value);
if (currentValue) {
combinedStyles.set("background", `${currentValue},${backgroundValue}`);
diff --git a/src/compiler/transformer/transforms/styles.test.js b/src/compiler/transformer/transforms/styles.test.js
index adf489d..8be63fd 100644
--- a/src/compiler/transformer/transforms/styles.test.js
+++ b/src/compiler/transformer/transforms/styles.test.js
@@ -54,24 +54,6 @@ test("applyStyles overrides backgrounds", (t) => {
});
});
-test("applyStyles stacks enclose over backgrounds", (t) => {
- const styles = new Map([
- ["enclose", "updiagonalstrike"],
- ["background", "red"],
- ]);
- const tag = {
- tag: "mrow",
- };
-
- t.deepEqual(applyStyles(styles, tag), {
- tag: "mrow",
- attrs: {
- style:
- "background:linear-gradient(to bottom right, transparent calc(50% - 0.1ex), currentColor calc(50% - 0.05ex), currentColor calc(50% + 0.05ex), transparent calc(50% + 0.1ex)),var(--mathup-background-red, red);",
- },
- });
-});
-
test("applyStyles conserves existing attrs", (t) => {
const styles = new Map([["color", "red"]]);
const tag = {
diff --git a/src/custom-element.js b/src/custom-element.js
index 88aebc3..7a4a4f2 100644
--- a/src/custom-element.js
+++ b/src/custom-element.js
@@ -4,6 +4,77 @@ import mathup from "./index.js";
const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
+// Replace with (when available):
+// import stylesheet from "./stylesheets/core.css" with { type: "css" };
+const stylesheet = new CSSStyleSheet();
+stylesheet.replaceSync(`
+ :is(
+ mo.mathup-function-application,
+ :not(mfrac, msub, msup, msubsup, munder, mover, munderover)
+ > :is(
+ .mathup-function-ident,
+ :is(msub, msup, msubsup, munder, mover, munderover):has(
+ > .mathup-function-ident:first-child
+ )
+ )
+ )
+ + :is(
+ mi,
+ mn,
+ :is(mrow, msub, msup, msubsup, munder, mover, munderover):has(
+ > :is(mn, mi):first-child
+ )
+ ),
+ :not(mfrac, msub, msup, msubsup, munder, mover, munderover)
+ > :is(
+ mi,
+ mo.mathup-function-application,
+ mo.mathup-invisible-times
+ )
+ + :is(
+ .mathup-function-ident,
+ :is(msub, msup, msubsup, munder, mover, munderover):has(
+ > .mathup-function-ident:first-child
+ )
+ ),
+ :not(mfrac, msub, msup, msubsup, munder, mover, munderover)
+ > :is(
+ mi,
+ mn,
+ mo.mathup-invisible-add,
+ mo.mathup-invisible-times,
+ :is(mrow, msub, msup, msubsup, munder, mover, munderover):has(
+ > :is(mi, mn):first-child
+ )
+ )
+ + mfrac,
+ :not(mfrac, msub, msup, msubsup, munder, mover, munderover)
+ > mfrac
+ + :is(
+ mi,
+ mn,
+ mfrac,
+ mroot,
+ msqrt,
+ mo.mathup-invisible-times,
+ :is(mrow, msub, msup, msubsup, munder, mover, munderover):has(
+ > :is(mi, mn):first-child
+ )
+ ) {
+ padding-inline-start: 0.35ex;
+ }
+
+ .mathup-enclose-cancel {
+ background: linear-gradient(
+ to bottom right,
+ transparent calc(50% - 0.1ex),
+ currentColor calc(50% - 0.05ex),
+ currentColor calc(50% + 0.05ex),
+ transparent calc(50% + 0.1ex)
+ );
+ }
+`);
+
const template = document.createElement("template");
{
const slot = document.createElement("slot");
@@ -21,6 +92,8 @@ export default class MathUpElement extends HTMLElement {
super();
const shadow = this.attachShadow({ mode: "open" });
+ shadow.adoptedStyleSheets = [stylesheet];
+
const shadowRoot =
/** @type {DocumentFragment} */
(template.content.cloneNode(true));
diff --git a/src/stylesheets/core.css b/src/stylesheets/core.css
new file mode 100644
index 0000000..2c4c59b
--- /dev/null
+++ b/src/stylesheets/core.css
@@ -0,0 +1,78 @@
+/* Space beween function ident and parentless parameter: sin θ */
+:is(
+ mo.mathup-function-application, /* sin .$ θ */
+ /* Prevent sin/cos */
+ :not(mfrac, msub, msup, msubsup, munder, mover, munderover)
+ > :is(
+ .mathup-function-ident,
+ :is(msub, msup, msubsup, munder, mover, munderover):has(
+ /* log_b n, sin^2 θ */
+ > .mathup-function-ident:first-child
+ )
+ )
+)
+ + :is(
+ mi,
+ mn,
+ :is(mrow, msub, msup, msubsup, munder, mover, munderover):has(
+ /* sin x^2 */
+ > :is(mn, mi):first-child
+ )
+),
+
+/* Space between ident and function ident: a sin */
+:not(mfrac, msub, msup, msubsup, munder, mover, munderover)
+ > :is(
+ mi,
+ mo.mathup-function-application, /* cos .$ sin */
+ mo.mathup-invisible-times /* a .* sin */
+ )
+ + :is(
+ .mathup-function-ident,
+ :is(msub, msup, msubsup, munder, mover, munderover):has(
+ /* a sin^2 */
+ > .mathup-function-ident:first-child
+ )
+),
+
+/* Space before fractions: a b/c */
+:not(mfrac, msub, msup, msubsup, munder, mover, munderover)
+ > :is(
+ mi,
+ mn,
+ mo.mathup-invisible-add, /* a .+ b/c */
+ mo.mathup-invisible-times, /* a .* b/c */
+ :is(mrow, msub, msup, msubsup, munder, mover, munderover):has(
+ /* a^2 b/c */
+ > :is(mi, mn):first-child
+ )
+ )
+ + mfrac,
+
+/* Space after fractions: b/c d */
+:not(mfrac, msub, msup, msubsup, munder, mover, munderover)
+ > mfrac
+ + :is(
+ mi,
+ mn,
+ mfrac,
+ mroot,
+ msqrt,
+ mo.mathup-invisible-times, /* b/c .* d */
+ :is(mrow, msub, msup, msubsup, munder, mover, munderover):has(
+ /* b/c d^2 */
+ > :is(mi, mn):first-child
+ )
+ ) {
+ padding-inline-start: 0.35ex;
+}
+
+.mathup-enclose-cancel {
+ background: linear-gradient(
+ to bottom right,
+ transparent calc(50% - 0.1ex),
+ currentColor calc(50% - 0.05ex),
+ currentColor calc(50% + 0.05ex),
+ transparent calc(50% + 0.1ex)
+ );
+}
diff --git a/test/snapshots/accents.js.snap b/test/snapshots/accents.js.snap
index b4c1ab0..ae586e9 100644
Binary files a/test/snapshots/accents.js.snap and b/test/snapshots/accents.js.snap differ
diff --git a/test/snapshots/basics.js.snap b/test/snapshots/basics.js.snap
index 2646480..879c668 100644
Binary files a/test/snapshots/basics.js.snap and b/test/snapshots/basics.js.snap differ
diff --git a/test/snapshots/colors.js.md b/test/snapshots/colors.js.md
index 300e1b5..d757192 100644
--- a/test/snapshots/colors.js.md
+++ b/test/snapshots/colors.js.md
@@ -96,18 +96,18 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 1
- ''
+ ''
> Snapshot 2
- ''
+ ''
## Cancel and background
> Snapshot 1
- ''
+ ''
> Snapshot 2
- ''
+ ''
diff --git a/test/snapshots/colors.js.snap b/test/snapshots/colors.js.snap
index 0884896..dcef853 100644
Binary files a/test/snapshots/colors.js.snap and b/test/snapshots/colors.js.snap differ
diff --git a/test/snapshots/enclosed.js.md b/test/snapshots/enclosed.js.md
index 40c445d..baefe7e 100644
--- a/test/snapshots/enclosed.js.md
+++ b/test/snapshots/enclosed.js.md
@@ -8,4 +8,4 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 1
- ''
+ ''
diff --git a/test/snapshots/enclosed.js.snap b/test/snapshots/enclosed.js.snap
index 9e29a67..316e2cc 100644
Binary files a/test/snapshots/enclosed.js.snap and b/test/snapshots/enclosed.js.snap differ
diff --git a/test/snapshots/fonts.js.snap b/test/snapshots/fonts.js.snap
index 5227c9a..4ee70ff 100644
Binary files a/test/snapshots/fonts.js.snap and b/test/snapshots/fonts.js.snap differ
diff --git a/test/snapshots/fractions.js.snap b/test/snapshots/fractions.js.snap
index 389d124..76cf3cb 100644
Binary files a/test/snapshots/fractions.js.snap and b/test/snapshots/fractions.js.snap differ
diff --git a/test/snapshots/groupings.js.snap b/test/snapshots/groupings.js.snap
index 3e3f8b5..0e9843f 100644
Binary files a/test/snapshots/groupings.js.snap and b/test/snapshots/groupings.js.snap differ
diff --git a/test/snapshots/identifiers.js.snap b/test/snapshots/identifiers.js.snap
index ffbeb53..b5ef9da 100644
Binary files a/test/snapshots/identifiers.js.snap and b/test/snapshots/identifiers.js.snap differ
diff --git a/test/snapshots/matrices.js.snap b/test/snapshots/matrices.js.snap
index ecd989a..47c1de7 100644
Binary files a/test/snapshots/matrices.js.snap and b/test/snapshots/matrices.js.snap differ
diff --git a/test/snapshots/numbers.js.snap b/test/snapshots/numbers.js.snap
index 9253bbe..763c310 100644
Binary files a/test/snapshots/numbers.js.snap and b/test/snapshots/numbers.js.snap differ
diff --git a/test/snapshots/operators.js.snap b/test/snapshots/operators.js.snap
index 33c6fa2..cfcb48f 100644
Binary files a/test/snapshots/operators.js.snap and b/test/snapshots/operators.js.snap differ
diff --git a/test/snapshots/options.js.snap b/test/snapshots/options.js.snap
index 3701561..f6198cd 100644
Binary files a/test/snapshots/options.js.snap and b/test/snapshots/options.js.snap differ
diff --git a/test/snapshots/roots.js.snap b/test/snapshots/roots.js.snap
index eb674f9..904f9c6 100644
Binary files a/test/snapshots/roots.js.snap and b/test/snapshots/roots.js.snap differ
diff --git a/test/snapshots/standard-functions.js.md b/test/snapshots/standard-functions.js.md
index f75154e..b7c5003 100644
--- a/test/snapshots/standard-functions.js.md
+++ b/test/snapshots/standard-functions.js.md
@@ -8,37 +8,37 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 1
- ''
+ ''
## The hyperbolic function
> Snapshot 1
- ''
+ ''
## Logarithm change of base
> Snapshot 1
- ''
+ ''
## Logarithm powers
> Snapshot 1
- ''
+ ''
## Logarithm division
> Snapshot 1
- ''
+ ''
## 2×2 determinants
> Snapshot 1
- ''
+ ''
## Fermats little theorem
diff --git a/test/snapshots/standard-functions.js.snap b/test/snapshots/standard-functions.js.snap
index f47e030..9d88011 100644
Binary files a/test/snapshots/standard-functions.js.snap and b/test/snapshots/standard-functions.js.snap differ
diff --git a/test/snapshots/sub-supscripts.js.md b/test/snapshots/sub-supscripts.js.md
index 4feddf0..6c51b17 100644
--- a/test/snapshots/sub-supscripts.js.md
+++ b/test/snapshots/sub-supscripts.js.md
@@ -74,13 +74,13 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 1
- ''
+ ''
## The natural logarithm
> Snapshot 1
- ''
+ ''
## Powers of powers of two
diff --git a/test/snapshots/sub-supscripts.js.snap b/test/snapshots/sub-supscripts.js.snap
index 86ad24b..233ac83 100644
Binary files a/test/snapshots/sub-supscripts.js.snap and b/test/snapshots/sub-supscripts.js.snap differ
diff --git a/test/snapshots/under-overscrips.js.snap b/test/snapshots/under-overscrips.js.snap
index 2927d4f..22e5103 100644
Binary files a/test/snapshots/under-overscrips.js.snap and b/test/snapshots/under-overscrips.js.snap differ
diff --git a/test/snapshots/whitespace.js.snap b/test/snapshots/whitespace.js.snap
index 425a562..d10e3f9 100644
Binary files a/test/snapshots/whitespace.js.snap and b/test/snapshots/whitespace.js.snap differ