temml 0.10.16 → 0.10.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 */
|