-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement command tokens and handlers in parser
For now only font commands are commands, previously these were styles and implemented along with other prefixes. Now commands will become new binary prefix nodes in the AST which can apply special commands on the nodes below. For fonts this means to some text transforms or add style attributes. In the future we might implement color #40 and align #39 with command tokens. **Language Changes** - Now you can stack some font commands to combine them. For example, if you want bold italic A you can write `bf it A`. Not all font commands stack though e.g. `fr bb` will not give you double-struck fraktur. **Output Changes** - With the exception of `mathvariant="normal"` we no longer use the `mathvariant` attribute. Instead we apply the relevant text transform directly and the unicode characters in the output (see #70). - Text gets some font commands applied via CSS (see #78). Specifically this is `bf`, `it`, `sf` and `tt` on texts (e.g. `bf tt "text"`). The latter two change the font-family of the output. If you want control of sans-serif and monospace fonts in the output you can set the CSS custom properties `--mathup-font-family-sans-serif` and `--mathup-font-family-monospace` respectively. **Breaking Changes** - Font commands now only applies to the first item in a term, previously it was applied on the entire term (see #77). `bf A_(i j)` would previously also boldface the indices (i j), but now it only boldfaces the matrix A. - Font commands will no longer unwrap fences around the operant. For example if you write `bf(A)` previously the parenteses would be stripped, and you would only end up with A. Now the parenteses are left as is. Resolves: #70 Resolves: #77 Resolves: #78
- Loading branch information
Showing
24 changed files
with
1,176 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import expr from "./expr.js"; | ||
|
||
/** | ||
* @typedef {import("../index.js").Node} Node | ||
* @typedef {import("../index.js").UnaryOperation} UnaryOperation | ||
* @typedef {import("../index.js").Term} Term | ||
*/ | ||
|
||
/** | ||
* @param {import("../parse.js").State} State | ||
* @return {{ node: UnaryOperation | Term, end: number }} | ||
*/ | ||
export default function command({ start, tokens }) { | ||
const token = tokens[start]; | ||
|
||
if (!token.name) { | ||
throw new Error("Got command token without a name"); | ||
} | ||
|
||
const textTransforms = []; | ||
|
||
if (token.name === "text-transform" && token.value) { | ||
textTransforms.push(token.value); | ||
} | ||
|
||
let pos = start + 1; | ||
let nextToken = tokens[pos]; | ||
while ( | ||
nextToken && | ||
(nextToken.type === "command" || nextToken.type === "space") | ||
) { | ||
if ( | ||
nextToken.type === "command" && | ||
nextToken.name === "text-transform" && | ||
token.value | ||
) { | ||
textTransforms.push(nextToken.value); | ||
} | ||
|
||
pos += 1; | ||
nextToken = tokens[pos]; | ||
} | ||
|
||
const next = expr({ stack: [], start: pos, tokens }); | ||
|
||
if (next.node.type === "Term") { | ||
// Only apply command to the first item in the term | ||
const [first, ...rest] = next.node.items; | ||
|
||
/** @type {Node[]} */ | ||
const items = first | ||
? [ | ||
{ | ||
type: "UnaryOperation", | ||
name: "command", | ||
transforms: textTransforms, | ||
items: [first], | ||
}, | ||
...rest, | ||
] | ||
: []; | ||
|
||
return { | ||
node: { | ||
type: "Term", | ||
items, | ||
}, | ||
end: next.end, | ||
}; | ||
} | ||
|
||
return { | ||
node: { | ||
type: "UnaryOperation", | ||
name: "command", | ||
transforms: textTransforms, | ||
items: [next.node], | ||
}, | ||
end: next.end, | ||
}; | ||
} |
Oops, something went wrong.