temml 0.10.16 → 0.10.18
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +2 -2
- package/contrib/copy-tex/README.md +42 -0
- package/contrib/copy-tex/copy-tex.js +66 -0
- package/contrib/copy-tex/copy-tex.min.js +1 -0
- package/dist/Temml-Asana.css +23 -3
- package/dist/Temml-Latin-Modern.css +21 -1
- package/dist/Temml-Libertinus.css +23 -3
- package/dist/Temml-Local.css +23 -3
- package/dist/Temml-STIX2.css +21 -1
- package/dist/temml.cjs +116 -30
- package/dist/temml.js +116 -30
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +116 -30
- package/dist/temmlPostProcess.js +1 -1
- package/package.json +1 -1
- package/src/buildMathML.js +14 -8
- package/src/environments/array.js +11 -9
- package/src/functions/accent.js +30 -0
- package/src/functions/delimsizing.js +15 -3
- package/src/functions/enclose.js +4 -1
- package/src/functions/hbox.js +5 -4
- package/src/functions/lap.js +1 -1
- package/src/functions/op.js +3 -1
- package/src/functions.js +1 -0
- package/src/macros.js +1 -2
- package/src/postProcess.js +1 -1
- package/src/symbols.js +10 -3
- package/temml.js +2 -2
package/README.md
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
| Library | Minified JavaScript + CSS |
|
4
4
|
|:--------------|:-------------------------:|
|
5
|
-
| Temml |
|
5
|
+
| Temml | 150 KB |
|
6
6
|
| MathJax 2.7.5 | 338 KB |
|
7
7
|
| KaTeX | 280 KB |
|
8
8
|
| TeXZilla | 168 KB |
|
9
9
|
|
10
|
-
As a futher advantage, Temml can use local system fonts. The minimum Temml installation serves a font file that is only
|
10
|
+
As a futher advantage, Temml can use local system fonts. The minimum Temml installation serves a font file that is only 10kb. Sadly, Chromium has some rendering bugs when using system fonts. It
|
11
11
|
work better with the Latin Modern font, a 380 KB file.
|
12
12
|
|
13
13
|
Temml’s coverage of LaTeX functions is as good as MathJax, slightly better than KaTeX 0.16.0 and substantially better than TeXZilla. See a [detailed coverage comparison](https://temml.org/docs/en/comparison.html).
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copy-tex extension
|
2
|
+
|
3
|
+
This extension modifies the copy/paste behavior in any browser supporting the
|
4
|
+
[Clipboard API][1] so that, when a user selects and copies `<math>` elements, the
|
5
|
+
text content of the resulting clipboard replaces `<math>` elements with their LaTeX
|
6
|
+
source surrounded by specified delimiters.
|
7
|
+
|
8
|
+
The default delimiters are `$…$` for inline math and `$$…$$` for display math,
|
9
|
+
but you can switch them to e.g. `\(…\)` and `\[…\]` by modifying
|
10
|
+
`copyDelimiters` in [the source code][2]. Note that a selection containing part
|
11
|
+
of a math element gets extended to include the entire element.
|
12
|
+
|
13
|
+
`<math>` elements must include an `<annotation>` element containing the LaTeX source,
|
14
|
+
so when you run Temml, be sure to include `annotate: "true"` in the Temml rendering
|
15
|
+
options.
|
16
|
+
|
17
|
+
Note that soft line breaks cannot co-exist with an `<annotation>` element. You’ll have
|
18
|
+
to choose one or the other.
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
This extension isn't part of Temml proper, so the script needs to be included
|
23
|
+
(via a `<script>` tag) in the page along with Temml itself. For example:
|
24
|
+
|
25
|
+
```
|
26
|
+
<head>
|
27
|
+
…
|
28
|
+
<link rel="stylesheet" href="./Temml-Local.css">
|
29
|
+
<script src="./temml.min.js"></script>
|
30
|
+
<script src="./copy-tex.min.js"></script>
|
31
|
+
…
|
32
|
+
</head>
|
33
|
+
```
|
34
|
+
|
35
|
+
See [copy-tex.html][3] for an example.
|
36
|
+
|
37
|
+
|
38
|
+
[1]: https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent
|
39
|
+
|
40
|
+
[2]: https://github.com/ronkok/Temml/tree/main/contrib/copy-tex/copy-tex.js
|
41
|
+
|
42
|
+
[3]: https://temml.org/copy-tex.html
|
@@ -0,0 +1,66 @@
|
|
1
|
+
// Mostly, a copy of Eric Demaine's copy-tex extension for KaTex
|
2
|
+
|
3
|
+
// Return <math> element, or null if not found.
|
4
|
+
function closestMath(node) {
|
5
|
+
// If node is a Text Node, for example, go up to containing Element,
|
6
|
+
// where we can apply the `closest` method.
|
7
|
+
const element = (node instanceof Element ? node : node.parentElement)
|
8
|
+
return element && element.closest('math')
|
9
|
+
}
|
10
|
+
|
11
|
+
const defaultCopyDelimiters = {
|
12
|
+
inline: ['$', '$'], // alternative: ['\(', '\)']
|
13
|
+
display: ['$$', '$$'] // alternative: ['\[', '\]']
|
14
|
+
};
|
15
|
+
|
16
|
+
// Replace math elements with their TeX source, given an <annotation> element.
|
17
|
+
function replaceMathwithTeX(fragment, copyDelimiters = defaultCopyDelimiters) {
|
18
|
+
const mathElements = fragment.querySelectorAll('math');
|
19
|
+
for (let i = 0; i < mathElements.length; i++) {
|
20
|
+
const element = mathElements[i];
|
21
|
+
const texSource = element.querySelector('annotation');
|
22
|
+
if (texSource) {
|
23
|
+
if (element.replaceWith) { element.replaceWith(texSource) }
|
24
|
+
texSource.innerHTML = copyDelimiters.inline[0] +
|
25
|
+
texSource.innerHTML + copyDelimiters.inline[1];
|
26
|
+
}
|
27
|
+
}
|
28
|
+
return fragment
|
29
|
+
}
|
30
|
+
|
31
|
+
// Global copy handler to modify behavior on/within math elements.
|
32
|
+
document.addEventListener('copy', function(event) {
|
33
|
+
const selection = window.getSelection()
|
34
|
+
if (selection.isCollapsed || !event.clipboardData) {
|
35
|
+
return // default action OK if selection is empty or unchangeable
|
36
|
+
}
|
37
|
+
const clipboardData = event.clipboardData
|
38
|
+
const range = selection.getRangeAt(0)
|
39
|
+
|
40
|
+
// When start point is within a formula, expand to entire formula.
|
41
|
+
const startMath = closestMath(range.startContainer);
|
42
|
+
if (startMath) {
|
43
|
+
range.setStartBefore(startMath)
|
44
|
+
}
|
45
|
+
|
46
|
+
// Similarly, when end point is within a formula, expand to entire formula.
|
47
|
+
const endMath = closestMath(range.endContainer);
|
48
|
+
if (endMath) {
|
49
|
+
range.setEndAfter(endMath)
|
50
|
+
}
|
51
|
+
|
52
|
+
const fragment = range.cloneContents()
|
53
|
+
if (!fragment.querySelector('annotation')) {
|
54
|
+
return // default action OK if no annotation elements
|
55
|
+
}
|
56
|
+
|
57
|
+
const htmlContents = Array.prototype.map.call(fragment.childNodes,
|
58
|
+
(el) => (el instanceof Text ? el.textContent : el.outerHTML)).join('')
|
59
|
+
|
60
|
+
// Preserve usual HTML copy/paste behavior.
|
61
|
+
clipboardData.setData('text/html', htmlContents)
|
62
|
+
// Rewrite plain-text version.
|
63
|
+
clipboardData.setData('text/plain', replaceMathwithTeX(fragment).textContent)
|
64
|
+
// Prevent normal copy handling.
|
65
|
+
event.preventDefault()
|
66
|
+
})
|
@@ -0,0 +1 @@
|
|
1
|
+
function closestMath(t){const e=t instanceof Element?t:t.parentElement;return e&&e.closest("math")}const defaultCopyDelimiters={inline:["$","$"],display:["$$","$$"]};function replaceMathwithTeX(t,e=defaultCopyDelimiters){const n=t.querySelectorAll("math");for(let t=0;t<n.length;t++){const o=n[t],a=o.querySelector("annotation");a&&(o.replaceWith&&o.replaceWith(a),a.innerHTML=e.inline[0]+a.innerHTML+e.inline[1])}return t}document.addEventListener("copy",(function(t){const e=window.getSelection();if(e.isCollapsed||!t.clipboardData)return;const n=t.clipboardData,o=e.getRangeAt(0),a=closestMath(o.startContainer);a&&o.setStartBefore(a);const r=closestMath(o.endContainer);r&&o.setEndAfter(r);const i=o.cloneContents();if(!i.querySelector("annotation"))return;const l=Array.prototype.map.call(i.childNodes,(t=>t instanceof Text?t.textContent:t.outerHTML)).join("");n.setData("text/html",l),n.setData("text/plain",replaceMathwithTeX(i).textContent),t.preventDefault()}));
|
package/dist/Temml-Asana.css
CHANGED
@@ -52,17 +52,37 @@ mo.prime-pad {
|
|
52
52
|
padding-left: 0.08em;
|
53
53
|
}
|
54
54
|
|
55
|
-
/*
|
55
|
+
/* Array cell justification in Firefox & WebKit */
|
56
|
+
.tml-right {
|
57
|
+
text-align: right;
|
58
|
+
}
|
59
|
+
.tml-left {
|
60
|
+
text-align: left;
|
61
|
+
}
|
62
|
+
|
63
|
+
/* Stretch \widetilde & set array cell justification in Chromium */
|
56
64
|
@supports (not (-webkit-backdrop-filter: blur(1px))) and (not (-moz-appearance: none)) {
|
57
65
|
.tml-crooked-2 {
|
58
66
|
transform: scale(2.0, 1.1)
|
59
67
|
}
|
60
68
|
.tml-crooked-3 {
|
61
|
-
transform: scale(3.0, 1.
|
69
|
+
transform: scale(3.0, 1.3)
|
62
70
|
}
|
63
71
|
.tml-crooked-4 {
|
64
|
-
transform: scale(4.0, 1.
|
72
|
+
transform: scale(4.0, 1.4)
|
73
|
+
}
|
74
|
+
.tml-right {
|
75
|
+
text-align: -webkit-right;
|
65
76
|
}
|
77
|
+
.tml-left {
|
78
|
+
text-align: -webkit-left;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
/* Adjust WebKit accents */
|
83
|
+
@supports (-webkit-backdrop-filter: blur(1px)) {
|
84
|
+
.tml-xshift { transform: translate(0px, 0.45em) }
|
85
|
+
.tml-capshift { transform: translate(0px, 0.35em) }
|
66
86
|
}
|
67
87
|
|
68
88
|
/* flex-wrap for line-breaking in Chromium */
|
@@ -62,7 +62,15 @@ mo.prime-pad {
|
|
62
62
|
padding-left: 0.08em;
|
63
63
|
}
|
64
64
|
|
65
|
-
/*
|
65
|
+
/* Array cell justification in Firefox & WebKit */
|
66
|
+
.tml-right {
|
67
|
+
text-align: right;
|
68
|
+
}
|
69
|
+
.tml-left {
|
70
|
+
text-align: left;
|
71
|
+
}
|
72
|
+
|
73
|
+
/* Stretch \widetilde & set array cell justification in Chromium */
|
66
74
|
@supports (not (-webkit-backdrop-filter: blur(1px))) and (not (-moz-appearance: none)) {
|
67
75
|
.tml-crooked-2 {
|
68
76
|
transform: scale(2.0, 1.1)
|
@@ -73,6 +81,18 @@ mo.prime-pad {
|
|
73
81
|
.tml-crooked-4 {
|
74
82
|
transform: scale(4.0, 1.4)
|
75
83
|
}
|
84
|
+
.tml-right {
|
85
|
+
text-align: -webkit-right;
|
86
|
+
}
|
87
|
+
.tml-left {
|
88
|
+
text-align: -webkit-left;
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
/* Adjust WebKit accents */
|
93
|
+
@supports (-webkit-backdrop-filter: blur(1px)) {
|
94
|
+
.tml-xshift { transform: translate(0px, 0.45em) }
|
95
|
+
.tml-capshift { transform: translate(0px, 0.35em) }
|
76
96
|
}
|
77
97
|
|
78
98
|
/* flex-wrap for line-breaking in Chromium */
|
@@ -59,17 +59,37 @@ mo.prime-pad {
|
|
59
59
|
padding-left: 0.08em;
|
60
60
|
}
|
61
61
|
|
62
|
-
/*
|
62
|
+
/* Array cell justification in Firefox & WebKit */
|
63
|
+
.tml-right {
|
64
|
+
text-align: right;
|
65
|
+
}
|
66
|
+
.tml-left {
|
67
|
+
text-align: left;
|
68
|
+
}
|
69
|
+
|
70
|
+
/* Stretch \widetilde & set array cell justification in Chromium */
|
63
71
|
@supports (not (-webkit-backdrop-filter: blur(1px))) and (not (-moz-appearance: none)) {
|
64
72
|
.tml-crooked-2 {
|
65
73
|
transform: scale(2.0, 1.1)
|
66
74
|
}
|
67
75
|
.tml-crooked-3 {
|
68
|
-
transform: scale(3.0, 1.
|
76
|
+
transform: scale(3.0, 1.3)
|
69
77
|
}
|
70
78
|
.tml-crooked-4 {
|
71
|
-
transform: scale(4.0, 1.
|
79
|
+
transform: scale(4.0, 1.4)
|
80
|
+
}
|
81
|
+
.tml-right {
|
82
|
+
text-align: -webkit-right;
|
72
83
|
}
|
84
|
+
.tml-left {
|
85
|
+
text-align: -webkit-left;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
/* Adjust WebKit accents */
|
90
|
+
@supports (-webkit-backdrop-filter: blur(1px)) {
|
91
|
+
.tml-xshift { transform: translate(0px, 0.45em) }
|
92
|
+
.tml-capshift { transform: translate(0px, 0.35em) }
|
73
93
|
}
|
74
94
|
|
75
95
|
/* flex-wrap for line-breaking in Chromium */
|
package/dist/Temml-Local.css
CHANGED
@@ -45,17 +45,37 @@ mo.prime-pad {
|
|
45
45
|
padding-left: 0.08em;
|
46
46
|
}
|
47
47
|
|
48
|
-
/*
|
48
|
+
/* Array cell justification in Firefox & WebKit */
|
49
|
+
.tml-right {
|
50
|
+
text-align: right;
|
51
|
+
}
|
52
|
+
.tml-left {
|
53
|
+
text-align: left;
|
54
|
+
}
|
55
|
+
|
56
|
+
/* Stretch \widetilde & set array cell justification in Chromium */
|
49
57
|
@supports (not (-webkit-backdrop-filter: blur(1px))) and (not (-moz-appearance: none)) {
|
50
58
|
.tml-crooked-2 {
|
51
59
|
transform: scale(2.0, 1.1)
|
52
60
|
}
|
53
61
|
.tml-crooked-3 {
|
54
|
-
transform: scale(3.0, 1.
|
62
|
+
transform: scale(3.0, 1.3)
|
55
63
|
}
|
56
64
|
.tml-crooked-4 {
|
57
|
-
transform: scale(4.0, 1.
|
65
|
+
transform: scale(4.0, 1.4)
|
66
|
+
}
|
67
|
+
.tml-right {
|
68
|
+
text-align: -webkit-right;
|
58
69
|
}
|
70
|
+
.tml-left {
|
71
|
+
text-align: -webkit-left;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
/* Adjust WebKit accents */
|
76
|
+
@supports (-webkit-backdrop-filter: blur(1px)) {
|
77
|
+
.tml-xshift { transform: translate(0px, 0.45em) }
|
78
|
+
.tml-capshift { transform: translate(0px, 0.35em) }
|
59
79
|
}
|
60
80
|
|
61
81
|
/* flex-wrap for line-breaking in Chromium */
|
package/dist/Temml-STIX2.css
CHANGED
@@ -53,7 +53,15 @@ mo.prime-pad {
|
|
53
53
|
padding-left: 0.08em;
|
54
54
|
}
|
55
55
|
|
56
|
-
/*
|
56
|
+
/* Array cell justification in Firefox & WebKit */
|
57
|
+
.tml-right {
|
58
|
+
text-align: right;
|
59
|
+
}
|
60
|
+
.tml-left {
|
61
|
+
text-align: left;
|
62
|
+
}
|
63
|
+
|
64
|
+
/* Stretch \widetilde & set array cell justification in Chromium */
|
57
65
|
@supports (not (-webkit-backdrop-filter: blur(1px))) and (not (-moz-appearance: none)) {
|
58
66
|
.tml-crooked-2 {
|
59
67
|
transform: scale(2.0, 1.1)
|
@@ -64,6 +72,18 @@ mo.prime-pad {
|
|
64
72
|
.tml-crooked-4 {
|
65
73
|
transform: scale(4.0, 1.4)
|
66
74
|
}
|
75
|
+
.tml-right {
|
76
|
+
text-align: -webkit-right;
|
77
|
+
}
|
78
|
+
.tml-left {
|
79
|
+
text-align: -webkit-left;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
/* Adjust WebKit accents */
|
84
|
+
@supports (-webkit-backdrop-filter: blur(1px)) {
|
85
|
+
.tml-xshift { transform: translate(0px, 0.45em) }
|
86
|
+
.tml-capshift { transform: translate(0px, 0.35em) }
|
67
87
|
}
|
68
88
|
|
69
89
|
/* flex-wrap for line-breaking in Chromium */
|