temml 0.10.16 → 0.10.17

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  | Library | Minified JavaScript + CSS |
4
4
  |:--------------|:-------------------------:|
5
- | Temml | 146 KB |
5
+ | Temml | 149 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 12kb. Sadly, Chromium has some rendering bugs when using system fonts. It
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()}));
@@ -52,17 +52,37 @@ mo.prime-pad {
52
52
  padding-left: 0.08em;
53
53
  }
54
54
 
55
- /* Stretch \widetilde in Chromium */
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.1)
69
+ transform: scale(3.0, 1.3)
62
70
  }
63
71
  .tml-crooked-4 {
64
- transform: scale(4.0, 1.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
- /* Stretch \widetilde in Chromium */
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
- /* Stretch \widetilde in Chromium */
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.1)
76
+ transform: scale(3.0, 1.3)
69
77
  }
70
78
  .tml-crooked-4 {
71
- transform: scale(4.0, 1.2)
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 */
@@ -45,17 +45,37 @@ mo.prime-pad {
45
45
  padding-left: 0.08em;
46
46
  }
47
47
 
48
- /* Stretch \widetilde in Chromium */
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.1)
62
+ transform: scale(3.0, 1.3)
55
63
  }
56
64
  .tml-crooked-4 {
57
- transform: scale(4.0, 1.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 */
@@ -53,7 +53,15 @@ mo.prime-pad {
53
53
  padding-left: 0.08em;
54
54
  }
55
55
 
56
- /* Stretch \widetilde in Chromium */
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 */