MathML-Muses Set of example and trial documents around MathML. Bias toward copy-and-paste and notations. 2022-09-20T00:07:51+00:00 https://mathmlmuses.netlify.app Paul Libbrecht About 2022-09-20T00:07:51+00:00 https://mathmlmuses.netlify.app/about/ <h2 id="why">Why?<a class="tdbc-anchor" href="#why">#</a></h2> <p>This collection of snippets is made to represent on the web a few attempts (&quot;musings&quot;) toward activating or observing features of MathML, present, past or future.</p> <h2 id="who-">Who ?<a class="tdbc-anchor" href="#who-">#</a></h2> <p>Currently maintained by <a href="https://hoplahup.net/paul/">Paul Libbrecht</a>.</p> <h2 id="when-">When ?<a class="tdbc-anchor" href="#when-">#</a></h2> <p>Started in 2021... with the hope that it gets bigger.</p> <h2 id="how">How?<a class="tdbc-anchor" href="#how">#</a></h2> <p>The website is built using <a href="https://www.11ty.dev/">11ty</a> based on <a href="https://11ty-netlify-jumpstart.netlify.app/">Stehanie Eckles Netlify Start</a>.</p> <p>The choice of infra brings an easy and clean publishing and flexible possibilities to stage all sorts of media-types and HTML forms as part of this endeavour includes exploring media-types for serving and exchanging MathML and the possibilities one reaches on browsers.</p> <p>The <a href="https://github.com/polx/mathmlmuses">source is on GitHub</a> and the site is hosted <a href="https://mathmlmuses.netlify.app/">on netlify</a>.</p> <h2 id="but-">But ?<a class="tdbc-anchor" href="#but-">#</a></h2> <p>Should you wish to suggest an enrichment, please make a fork and pull-request. Or just <a href="https://hoplahup.net/paul/contacts.html">contact me</a> or speak up <a href="https://twitter.com/polx">on twitter</a>.</p> Intents as CSS 2022-09-20T00:07:51+00:00 https://mathmlmuses.netlify.app/intents-as-css-styles/ <h2 id="mathml-intents">MathML Intents<a class="tdbc-anchor" href="#mathml-intents">#</a></h2> <p>MathML Intents is a proposed evolution to be elaborated within MathML4, a specification that is to be produced by the newly formed <a href="https://www.w3.org/Math/">Math Working Group of the W3C</a></p> <p>Intents should help into making loud-readable mathematical formulæ written in presentation MathML. A rich start of &quot;default intents&quot; has been compiled in <a href="https://docs.google.com/spreadsheets/d/e/2PACX-1vTD9H2hQjgXXbkZrqkJQbTawwwrvlDfrTlVZRY8iF49jkJZ2rYfQX4QK39GlLhIuK0Fhhwkm_NnAcqm/pubhtml">this table</a>. Intents could give a hint toward bringing some <em>semantic</em> into MathML-presentation expressions.</p> <p>However, it is clear that such a list is never going to be one-size fits all. Some of main symbols my favorite math topics are not there (e.g. the amalgamated product of finitely generated groups or the homotopy groups) and different ways of saying will always come e.g. the pipe when in P(A|B) or in {x| x&gt;3} (non-use of a math-specific syntax is intentional ;-)). One plans an intent attribute value to be puttable on every MathML-presentation element. That's good and useful for specific intents. But repeating that the &quot;|&quot;-symbol should be said as a <em>conditional to</em> and not a <em>such that</em> bloats the source.</p> <hr> <h2 id="what-if">What if...<a class="tdbc-anchor" href="#what-if">#</a></h2> <p>... the <code>intent</code> attribute value could be specified by using styles of the cascading stylesheet. Let us suppose, for example, that a <code>mathintent-&lt;intent-pattern&gt;</code> property value of CSS exists for each thinkable intent-pattern (that's the <em>known notation</em> in <a href="https://docs.google.com/spreadsheets/d/e/2PACX-1vTD9H2hQjgXXbkZrqkJQbTawwwrvlDfrTlVZRY8iF49jkJZ2rYfQX4QK39GlLhIuK0Fhhwkm_NnAcqm/pubhtml">the intent values table</a>).</p> <p>This means that this property can be put inside a rule within the web-page body or within a stylesheet and indicate:</p> <ul> <li>an intent value for every occurrence of a particular MathML-element's pattern (as is done in the list)</li> <li>an intent value for such but within a particular class (e.g. an indication that a given expression is in probability-theory, e.g. <nobr>P(A|B)</nobr> or that other is a set description as in <nobr>{x | x² &gt; 1}</nobr>.</li> </ul> <p>And it also probably means that the best practice where CSS has been applied to accessibility such as the reading-mode of browsers, the high-contrast skin-change, or user-adjustments can all be made too.</p> <hr> <h2 id="examples">Examples<a class="tdbc-anchor" href="#examples">#</a></h2> <h3 id="translating">Translating<a class="tdbc-anchor" href="#translating">#</a></h3> <p>An author wishes to write down and make effective in his web-publications in, say, German. For this, he wishes to apply translations of the intents for his notations. His usage of mathematical symbols is rather moderate and he holds a table of symbols at the introduction of his web-publications anyways.</p> <p>Thus our author realizes a stylesheet for its his web-publication so that it is enough to write presentation MathML and have them speak-aloud-pronounceable in German.</p> <p>A slight extract could be the following, where the suffix after <code>mathintent</code> should be read as a pattern of MathML element names and character names either as entity or unicode names.</p> <pre class="language-css"><code class="language-css"> <span class="token selector">*[lang="de"]</span> <span class="token punctuation">{</span><br> <span class="token property">mathintent-mo-equal</span><span class="token punctuation">:</span> <span class="token string">"$1 gleich $2"</span><span class="token punctuation">;</span><br> <span class="token property">mathintent-mo-lt</span><span class="token punctuation">:</span> <span class="token string">"$1 kleiner als $2"</span><span class="token punctuation">;</span><br> <span class="token property">mathintent-mi-cm</span><span class="token punctuation">:</span> <span class="token string">"Zentimeter"</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span></code></pre> <h3 id="mark-context-to-choose-intent">Mark context to choose intent<a class="tdbc-anchor" href="#mark-context-to-choose-intent">#</a></h3> <p>While the list of intents provides an intent for many symbol patterns, there may be a lot of ambiguity left. As an example <code>&lt;mo&gt;|&lt;/mo&gt;</code> could be automatically endowed with:</p> <ul> <li>the intent <code>such-that</code> with a speech hint <code>$1 such that $2</code></li> <li>the intent <code>conditional-probability</code> with a speech hint <code>$1 given $2</code></li> </ul> <p>Supposing that the following stylesheet can be written:</p> <pre class="language-css"><code class="language-css"> <span class="token selector">.conditional-prob</span> <span class="token punctuation">{</span><br> <span class="token property">mathintent-mo-mid</span><span class="token punctuation">:</span> <span class="token string">"$1 given $2"</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br> <span class="token selector">.set</span> <span class="token punctuation">{</span><br> <span class="token property">mathintent-mo-mid</span><span class="token punctuation">:</span> <span class="token string">"$1 such that $2"</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span></code></pre> <p>Note that <code>mid</code> is the name of the entity of the pipe character, it could have been <code>DIVIDES</code> (the unicode name), <code>VerticalBar</code> or... The above stylesheet could then be used in the following expressions:</p> <pre class="language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>math</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mrow</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>conditional-prob<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>P<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>(<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mi</span><span class="token punctuation">></span></span>A<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mi</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>|<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mi</span><span class="token punctuation">></span></span>B<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mi</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mrow</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>=<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mrow</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>set<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>P<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>(<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mfenced</span> <span class="token attr-name">open</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>{<span class="token punctuation">"</span></span> <span class="token attr-name">close</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mrow</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mi</span><span class="token punctuation">></span></span>x<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mi</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>|<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>msup</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mi</span><span class="token punctuation">></span></span>x<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mi</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mn</span><span class="token punctuation">></span></span>2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mn</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>msup</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span><span class="token entity named-entity" title="&gt;">&amp;gt;</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mn</span><span class="token punctuation">></span></span>1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mn</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mrow</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mfenced</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mrow</span><span class="token punctuation">></span></span><br><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>math</span><span class="token punctuation">></span></span></code></pre> <h3 id="scoping-by-classname">Scoping by classname<a class="tdbc-anchor" href="#scoping-by-classname">#</a></h3> <p>A magazine or conference web-site presents the abstracts of the various contributions. Some abstracts are from different communities so that, say, the expression <em>A~B</em> should either be pronounced as <em>A is congruent to B</em> or as <em>A follows the distribution B</em>.</p> <p>Because each abstract can be tagged with a classname denoting the &quot;area&quot; it belongs to. The different intents are inherited without the editor actually modifying the MathML expressions of each of the abstracts.</p> <hr> <h2 id="challenges-&amp;-hopes">Challenges &amp; Hopes<a class="tdbc-anchor" href="#challenges-&amp;-hopes">#</a></h2> <p>Supposing that this becomes widespread practice (indeed, accesibility is becoming more and more of a legal requirement and intents bring an operational way to do so), collecting the stylesheets found around the web could offer a way to complement and, more a challenge, <strong>collect translations</strong> in multiple languages and communities for the intents' table (the one above really is for the English-speakers only).</p> <p>Accessibility devices that work with browsers don't get the CSS... That is a problem if operating on mandate of a browser that has loaded a static HTML page. However, CSS inheritance works rather well in most browsers and could, thus, be ported to attributes of the DOM by a JavaScript running in the browser before the accessibility device is addressed. More concretely, the javascript piece would request all inherited properties on any given node and then apply, say, <code>mathintent-mo-mid: &quot;$1 given $2&quot;</code> on all children of <code>&lt;mrow class=&quot;set&quot;&gt;</code> which can become an explicit style attribute which the accessibility tool can then use. The idea is that such a style attribute is interpreted before the general table of default intents and it can <em>fire</em> with more priority than it. This offers a way for authors to create context... and hopefully for authors of the table of default intents to take advantage of it to find more intents in different contexts (math domains, languages...).</p> <p>Changing stylesheet to adjust the purpose might be useful here too: Creating different stylesheets for different recipients and customising stylesheet because of one's stronger knowledge might help the users of accessibility devices obtain a more relevant experience. The change could be in the browser level, at the level of a classroom, at the level of an author, or even at the software level.</p> <p>And if CSS is still not the right selection language for the stylesheets to be authored... there's a lot of generator out there: You can really industrialize the production of the CSS rules that will produce intents to be applied to the very specific category or media.</p> <hr> <h2 id="now-what">Now what?<a class="tdbc-anchor" href="#now-what">#</a></h2> <p>This little &quot;what-if musing&quot; was written to enrich the discussion in the Math community and working group. After a first <a href="https://lists.w3.org/Archives/Public/public-mathml4/2021May/0001.html">announce</a>, David Farmer and Deyan Ginev commented which resulted to the introduction of a property prefix.</p> ClipOps 2 2022-09-20T00:07:51+00:00 https://mathmlmuses.netlify.app/tryMathML-Copy-CustomTypes/ <h3>Idea</h3> <p>The current <a href="https://www.w3.org/TR/2021/WD-clipboard-apis-20210806/">Async clipboard APIs specification</a> is out and allows, after permission, JavaScript pages to invoke copy (write to clipboard) or paste (read from clipboard) when they deem it useful. That is very nice as users start to be aware that permissions is something they could give and trust. As we are on the web, it means that what is copied remains <i>sanitized</i>: a picture is rendered then re-serialized, HTML gets devoided of anything slightly suspicious, the rest is removed.</p> <p>But what is more exciting is that custom types are coming: JavaScript in a page can, for implementing browsers, specify content types that will get transmitted for other apps or other web pages to use.</p> <p>A proposed specification <a href="https://github.com/w3c/clipboard-apis/blob/custom-format-spec/index.bs">pull-request</a> (an amendment) has been made that would allow the content-types to be named with a prefix "web " (web followed by a space, this idea of @annevk makes it impossible to parse a media type out of that) to be put into the clipboard using the same operations. Reveiving web-pages would look for the same pattern and are warned that this is raw content: Depending on the processing, the content must be sanitized (e.g. if put within a web-page, one should avoid to transport trackers or candidate web page attacks).</p> <h3>Application</h3> <p>Here we have a small equation in MathML (from <a href="https://dlmf.nist.gov/14.13">here</a>) and a button to copy it:</p> <p id="simpleExpression" style="text-align:center"><math xmlns="http://www.w3.org/1998/Math/MathML" displaystyle="true"> <mrow> <mrow> <mrow> <msubsup> <mi mathvariant="sans-serif" title="Ferrers function of the first kind">P</mi> <mi title="general degree">&#x3BD;</mi> <mi title="general order">&#x3BC;</mi> </msubsup> <mo>&#x2061;</mo> <mrow> <mo>(</mo> <mrow> <mi title="cosine function">cos</mi> <mo>&#x2061;</mo> <mi title="variable">&#x3B8;</mi> </mrow> <mo>)</mo> </mrow> </mrow> <mo>=</mo> <mrow> <mfrac> <mrow> <msup> <mn>2</mn> <mrow> <mi title="general order">&#x3BC;</mi> <mo>+</mo> <mn>1</mn> </mrow> </msup> <mo>&#x2062;</mo> <msup> <mrow> <mo stretchy="false">(</mo> <mrow> <mi title="sine function">sin</mi> <mo>&#x2061;</mo> <mi title="variable">&#x3B8;</mi> </mrow> <mo stretchy="false">)</mo> </mrow> <mi title="general order">&#x3BC;</mi> </msup> </mrow> <msup> <mi title="the ratio of the circumference of a circle to its diameter">&#x3C0;</mi> <mrow> <mn>1</mn> <mo>/</mo> <mn>2</mn> </mrow> </msup> </mfrac> <mo>&#x2062;</mo> <mrow> <munderover> <mo largeop="true" movablelimits="false" symmetric="true">&#x2211;</mo> <mrow> <mi>k</mi> <mo>=</mo> <mn>0</mn> </mrow> <mi mathvariant="normal">&#x221E;</mi> </munderover> <mrow> <mfrac> <mrow> <mi mathvariant="normal" title="gamma function">&#x393;</mi> <mo>&#x2061;</mo> <mrow> <mo>(</mo> <mrow> <mi title="general degree">&#x3BD;</mi> <mo>+</mo> <mi title="general order">&#x3BC;</mi> <mo>+</mo> <mi>k</mi> <mo>+</mo> <mn>1</mn> </mrow> <mo>)</mo> </mrow> </mrow> <mrow> <mi mathvariant="normal" title="gamma function">&#x393;</mi> <mo>&#x2061;</mo> <mrow> <mo>(</mo> <mrow> <mi title="general degree">&#x3BD;</mi> <mo>+</mo> <mi>k</mi> <mo>+</mo> <mfrac> <mn>3</mn> <mn>2</mn> </mfrac> </mrow> <mo>)</mo> </mrow> </mrow> </mfrac> <mo>&#x2062;</mo> <mfrac> <msub> <mrow> <mo title="Pochhammer&#x2019;s symbol (or shifted factorial)">(</mo> <mrow> <mi title="general order">&#x3BC;</mi> <mo>+</mo> <mfrac> <mn>1</mn> <mn>2</mn> </mfrac> </mrow> <mo title="Pochhammer&#x2019;s symbol (or shifted factorial)">)</mo> </mrow> <mi>k</mi> </msub> <mrow> <mi>k</mi> <mo title="factorial (as in ! n )">!</mo> </mrow> </mfrac> <mo>&#x2062;</mo> <mrow> <mi title="sine function">sin</mi> <mo>&#x2061;</mo> <mrow> <mo>(</mo> <mrow> <mrow> <mo stretchy="false">(</mo> <mrow> <mi title="general degree">&#x3BD;</mi> <mo>+</mo> <mi title="general order">&#x3BC;</mi> <mo>+</mo> <mrow> <mn>2</mn> <mo>&#x2062;</mo> <mi>k</mi> </mrow> <mo>+</mo> <mn>1</mn> </mrow> <mo stretchy="false">)</mo> </mrow> <mo>&#x2062;</mo> <mi title="variable">&#x3B8;</mi> </mrow> <mo>)</mo> </mrow> </mrow> </mrow> </mrow> </mrow> </mrow> </mrow> </math> </p> <p><button id="asyncCopyButton" onclick="fadeButtonIn(); asyncCopy()">copy the expression</button></p> <p>Note that the copy only works on Blink-generation Chromium (or Edge) from version 105 upwards. There, the MathML does only display if you activate "Experimental Web Platform features" from the "chrome://flags/" URL!</p> <p>A you can see in the source, the copy button writes two blobs into the clipboard:</p> <ul> <li><code>web application/mathml+xml</code> the generic type</li> <li><code>web application/mathml-presentation+xml</code> the specific type for MathML-presentation</li> </ul> <h3>Result</h3> <p>Expected: On some platforms and using some browsers the clipboard flavour for MathML should appear so that desktop apps could consume what was copied (e.g. from a web-page of a textbook). We're close to this.</p> <p>The obtained result on my macOS today (2022-09-16) is close to this:</p> <ul> <li><code>com.web.custom.format0</code> containing our MathML source</li> <li><code>com.web.custom.format1</code> containing it too</li> <li><code>com.web.custom.format.map</code> containing a json record as follows:<br> <i>{"application/mathml+xml":"com.web.custom.format0",<br> "application/mathml-presentation+xml":"com.web.custom.format1"}</i></li> </ul> <h3>Conclusion</h3> <p>Web pages will be able to produce rich MathML content using JavaScript. Most probably formula input-editors, formula enrichment or display systems such as MathJax, web-sites with lots of formulæ such as DLMF or wikipedia will all be able to take advantage of this. That looks like a content that is ready to be used by desktop apps, once they know that they have the proper sanitization in place.</p> <p>It also seems that desktop apps can produce this. Well... it seems interoperable!</p> <p>I feel slightly unsafe on the permissions: Can it be that I forget that I allowed access to clipboard? Probably the permissions won't last long. As another drawback this implementation is not yet standardized... which makes it fragile.</p> <p>Optimistic note: Since the code in the page is doing the copy, it is also responsible to support the selection of a portion of the expression to be copied. It is true that this is not as declarative as simple markup but it will let page authors get their say in the selection: e.g. extending a selection of a+b-c+5 from "+b-" to "a+b+c".</p> <h3>Acknowledgement</h3> <p>Thanks @snianu for pushing and developing <a href="https://github.com/w3c/clipboard-apis/blob/custom-format-spec/index.bs">the custom types</a> spec, for @tomayac for making the <a href="https://developer.chrome.com/blog/web-custom-formats-for-the-async-clipboard-api/">helpful blog page</a> and demo at TPAC 2022, for the project <a href="https://fugu-tracker.web.app/">Fugu's streamlining of APIs</a> and for @garykac for keeping on track of the clipboard API spec. </p> <script> async function asyncCopy() { try { const mml = document.getElementById("simpleExpression").innerHTML; const blob = new Blob([mml],{type: 'application/mathml+xml'}); const blob2 = new Blob([mml],{type: 'application/mathml-presentation+xml'}); const clipboardItem = new ClipboardItem({ ['web ' + blob.type]:blob, ['web ' + blob2.type]:blob2, }) await navigator.clipboard.write([clipboardItem]); } catch (e) { console.warn(e); } } function fadeButtonIn() { const elt = document.getElementById("asyncCopyButton") let step = 0, max = 20; let colorize = () => { step++; if(step<10) color = 10*step; else color = 10-(step-10)*10; console.log("color " + color) elt.style.backgroundColor = "rgb(" + color + "," + color + "," + color + "," + color + ")" if(step<=max) window.setTimeout(colorize,100) } window.setTimeout(colorize, 100) } window.addEventListener("load", () => { const elt = document.getElementById("asyncCopyButton") if (typeof(navigator.clipboard.write)=="undefined") { elt.setAttribute("disabled", "true") elt.innerText = " -- function navigator.clipboard.write not found -- " } }) </script> ClipOps 1 2022-09-20T00:07:51+00:00 https://mathmlmuses.netlify.app/tryMathml-Copy-oldstyle/ <h3>Basic idea</h3> <p>Any text copied from this page (using the normal copy mechanism) is copied as capitalized plain text (following <a href="https://www.sitepoint.com/clipboard-api/">here</a>) and with an extra flavour of <a href="https://www.w3.org/TR/mathml-media-types/">MathML media type</a> (a simple fraction in presentation MathML).</p> <p>Please look at the source code which has a script element showing the simple process.</p> <h3>Result</h3> <p>Expected: On some platforms and using some browsers the clipboard flavour for MathML should appear so that desktop apps could consume what was copied (e.g. from a web-page of a textbook).</p> <p>The obtained result is in the following pictures:</p> <p>Chromium 108: <img src="https://mathmlmuses.netlify.app/img/copied-mathml-oldstyle-chromium.png"></p> <p>Firefox 105: <img src="https://mathmlmuses.netlify.app/img/copied-mathml-oldstyle-firefox.png"></p> <p>Safari 15.6: <img src="https://mathmlmuses.netlify.app/img/copied-mathml-oldstyle-webkit.png"></p> <h3>Conclusion</h3> <p>It is hard to say if these private formats have a hope to be specified or applicable. Or if they're going to stay at all. Maybe this is the reason why softwares such as Word prefer to do content-sniffing, detecting MathML in the plain-text.</p> <p>I must say... this shows well that the current formula copy and paste does not work well, as you can see in <a href="https://www.w3.org/2022/09/TPAC/demos/mathml-formulae.html">this video</a>.</p> <script> window.addEventListener("load", () => { document.body.addEventListener('copy', copyHandler); // cut or copy event handler async function copyHandler(e) { const selection = document.getSelection(); // send uppercase text to clipboard e.clipboardData.setData( 'text/plain', selection.toString().toUpperCase() ); e.clipboardData.setData('application/mathml+xml', '<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>'); //e.clipboardData.setData('text/html', '<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>'); // stop default cut/copy e.preventDefault(); } }); async function asyncCopy() { try { const blob = new Blob(['<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>'],{type: 'text/html'}); const blob2 = new Blob(['<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>'], {type: 'application/mathml+xml'}) const clipboardItem = new ClipboardItem({ ['web application/mathml+xml']:blob2, ['text/html']: blob, //['web application/mathml+xml']:'<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>', //['web text/html']: '<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>' }) await navigator.clipboard.write([clipboardItem]); } catch (e) { console.warn(e); } } </script>
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<feed xmlns="http://www.w3.org/2005/Atom">
<title>MathML-Muses</title>
<subtitle>Set of example and trial documents around MathML. Bias toward copy-and-paste and notations.</subtitle>
<link href="https://mathmlmuses.netlify.app/feed/" rel="self"/>
<link href="https://mathmlmuses.netlify.app"/>
<updated>2022-09-20T00:07:51+00:00</updated>
<id>https://mathmlmuses.netlify.app</id>
<author>
<name>Paul Libbrecht</name>
</author>
<entry>
<title>About</title>
<link href="https://mathmlmuses.netlify.app/about/"/>
<updated>2022-09-20T00:07:51+00:00</updated>
<id>https://mathmlmuses.netlify.app/about/</id>
<content type="html"><h2 id="why">Why?<a class="tdbc-anchor" href="#why">#</a></h2> <p>This collection of snippets is made to represent on the web a few attempts (&quot;musings&quot;) toward activating or observing features of MathML, present, past or future.</p> <h2 id="who-">Who ?<a class="tdbc-anchor" href="#who-">#</a></h2> <p>Currently maintained by <a href="https://hoplahup.net/paul/">Paul Libbrecht</a>.</p> <h2 id="when-">When ?<a class="tdbc-anchor" href="#when-">#</a></h2> <p>Started in 2021... with the hope that it gets bigger.</p> <h2 id="how">How?<a class="tdbc-anchor" href="#how">#</a></h2> <p>The website is built using <a href="https://www.11ty.dev/">11ty</a> based on <a href="https://11ty-netlify-jumpstart.netlify.app/">Stehanie Eckles Netlify Start</a>.</p> <p>The choice of infra brings an easy and clean publishing and flexible possibilities to stage all sorts of media-types and HTML forms as part of this endeavour includes exploring media-types for serving and exchanging MathML and the possibilities one reaches on browsers.</p> <p>The <a href="https://github.com/polx/mathmlmuses">source is on GitHub</a> and the site is hosted <a href="https://mathmlmuses.netlify.app/">on netlify</a>.</p> <h2 id="but-">But ?<a class="tdbc-anchor" href="#but-">#</a></h2> <p>Should you wish to suggest an enrichment, please make a fork and pull-request. Or just <a href="https://hoplahup.net/paul/contacts.html">contact me</a> or speak up <a href="https://twitter.com/polx">on twitter</a>.</p> </content>
</entry>
<entry>
<title>Intents as CSS</title>
<link href="https://mathmlmuses.netlify.app/intents-as-css-styles/"/>
<updated>2022-09-20T00:07:51+00:00</updated>
<id>https://mathmlmuses.netlify.app/intents-as-css-styles/</id>
<content type="html"><h2 id="mathml-intents">MathML Intents<a class="tdbc-anchor" href="#mathml-intents">#</a></h2> <p>MathML Intents is a proposed evolution to be elaborated within MathML4, a specification that is to be produced by the newly formed <a href="https://www.w3.org/Math/">Math Working Group of the W3C</a></p> <p>Intents should help into making loud-readable mathematical formulæ written in presentation MathML. A rich start of &quot;default intents&quot; has been compiled in <a href="https://docs.google.com/spreadsheets/d/e/2PACX-1vTD9H2hQjgXXbkZrqkJQbTawwwrvlDfrTlVZRY8iF49jkJZ2rYfQX4QK39GlLhIuK0Fhhwkm_NnAcqm/pubhtml">this table</a>. Intents could give a hint toward bringing some <em>semantic</em> into MathML-presentation expressions.</p> <p>However, it is clear that such a list is never going to be one-size fits all. Some of main symbols my favorite math topics are not there (e.g. the amalgamated product of finitely generated groups or the homotopy groups) and different ways of saying will always come e.g. the pipe when in P(A|B) or in {x| x&gt;3} (non-use of a math-specific syntax is intentional ;-)). One plans an intent attribute value to be puttable on every MathML-presentation element. That's good and useful for specific intents. But repeating that the &quot;|&quot;-symbol should be said as a <em>conditional to</em> and not a <em>such that</em> bloats the source.</p> <hr> <h2 id="what-if">What if...<a class="tdbc-anchor" href="#what-if">#</a></h2> <p>... the <code>intent</code> attribute value could be specified by using styles of the cascading stylesheet. Let us suppose, for example, that a <code>mathintent-&lt;intent-pattern&gt;</code> property value of CSS exists for each thinkable intent-pattern (that's the <em>known notation</em> in <a href="https://docs.google.com/spreadsheets/d/e/2PACX-1vTD9H2hQjgXXbkZrqkJQbTawwwrvlDfrTlVZRY8iF49jkJZ2rYfQX4QK39GlLhIuK0Fhhwkm_NnAcqm/pubhtml">the intent values table</a>).</p> <p>This means that this property can be put inside a rule within the web-page body or within a stylesheet and indicate:</p> <ul> <li>an intent value for every occurrence of a particular MathML-element's pattern (as is done in the list)</li> <li>an intent value for such but within a particular class (e.g. an indication that a given expression is in probability-theory, e.g. <nobr>P(A|B)</nobr> or that other is a set description as in <nobr>{x | x² &gt; 1}</nobr>.</li> </ul> <p>And it also probably means that the best practice where CSS has been applied to accessibility such as the reading-mode of browsers, the high-contrast skin-change, or user-adjustments can all be made too.</p> <hr> <h2 id="examples">Examples<a class="tdbc-anchor" href="#examples">#</a></h2> <h3 id="translating">Translating<a class="tdbc-anchor" href="#translating">#</a></h3> <p>An author wishes to write down and make effective in his web-publications in, say, German. For this, he wishes to apply translations of the intents for his notations. His usage of mathematical symbols is rather moderate and he holds a table of symbols at the introduction of his web-publications anyways.</p> <p>Thus our author realizes a stylesheet for its his web-publication so that it is enough to write presentation MathML and have them speak-aloud-pronounceable in German.</p> <p>A slight extract could be the following, where the suffix after <code>mathintent</code> should be read as a pattern of MathML element names and character names either as entity or unicode names.</p> <pre class="language-css"><code class="language-css"> <span class="token selector">*[lang="de"]</span> <span class="token punctuation">{</span><br> <span class="token property">mathintent-mo-equal</span><span class="token punctuation">:</span> <span class="token string">"$1 gleich $2"</span><span class="token punctuation">;</span><br> <span class="token property">mathintent-mo-lt</span><span class="token punctuation">:</span> <span class="token string">"$1 kleiner als $2"</span><span class="token punctuation">;</span><br> <span class="token property">mathintent-mi-cm</span><span class="token punctuation">:</span> <span class="token string">"Zentimeter"</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span></code></pre> <h3 id="mark-context-to-choose-intent">Mark context to choose intent<a class="tdbc-anchor" href="#mark-context-to-choose-intent">#</a></h3> <p>While the list of intents provides an intent for many symbol patterns, there may be a lot of ambiguity left. As an example <code>&lt;mo&gt;|&lt;/mo&gt;</code> could be automatically endowed with:</p> <ul> <li>the intent <code>such-that</code> with a speech hint <code>$1 such that $2</code></li> <li>the intent <code>conditional-probability</code> with a speech hint <code>$1 given $2</code></li> </ul> <p>Supposing that the following stylesheet can be written:</p> <pre class="language-css"><code class="language-css"> <span class="token selector">.conditional-prob</span> <span class="token punctuation">{</span><br> <span class="token property">mathintent-mo-mid</span><span class="token punctuation">:</span> <span class="token string">"$1 given $2"</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br> <span class="token selector">.set</span> <span class="token punctuation">{</span><br> <span class="token property">mathintent-mo-mid</span><span class="token punctuation">:</span> <span class="token string">"$1 such that $2"</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span></code></pre> <p>Note that <code>mid</code> is the name of the entity of the pipe character, it could have been <code>DIVIDES</code> (the unicode name), <code>VerticalBar</code> or... The above stylesheet could then be used in the following expressions:</p> <pre class="language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>math</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mrow</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>conditional-prob<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>P<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>(<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mi</span><span class="token punctuation">></span></span>A<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mi</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>|<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mi</span><span class="token punctuation">></span></span>B<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mi</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mrow</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>=<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mrow</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>set<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>P<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>(<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mfenced</span> <span class="token attr-name">open</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>{<span class="token punctuation">"</span></span> <span class="token attr-name">close</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mrow</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mi</span><span class="token punctuation">></span></span>x<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mi</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span>|<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>msup</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mi</span><span class="token punctuation">></span></span>x<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mi</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mn</span><span class="token punctuation">></span></span>2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mn</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>msup</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mo</span><span class="token punctuation">></span></span><span class="token entity named-entity" title="&gt;">&amp;gt;</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mo</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mn</span><span class="token punctuation">></span></span>1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mn</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mrow</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mfenced</span><span class="token punctuation">></span></span><br> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mrow</span><span class="token punctuation">></span></span><br><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>math</span><span class="token punctuation">></span></span></code></pre> <h3 id="scoping-by-classname">Scoping by classname<a class="tdbc-anchor" href="#scoping-by-classname">#</a></h3> <p>A magazine or conference web-site presents the abstracts of the various contributions. Some abstracts are from different communities so that, say, the expression <em>A~B</em> should either be pronounced as <em>A is congruent to B</em> or as <em>A follows the distribution B</em>.</p> <p>Because each abstract can be tagged with a classname denoting the &quot;area&quot; it belongs to. The different intents are inherited without the editor actually modifying the MathML expressions of each of the abstracts.</p> <hr> <h2 id="challenges-&amp;-hopes">Challenges &amp; Hopes<a class="tdbc-anchor" href="#challenges-&amp;-hopes">#</a></h2> <p>Supposing that this becomes widespread practice (indeed, accesibility is becoming more and more of a legal requirement and intents bring an operational way to do so), collecting the stylesheets found around the web could offer a way to complement and, more a challenge, <strong>collect translations</strong> in multiple languages and communities for the intents' table (the one above really is for the English-speakers only).</p> <p>Accessibility devices that work with browsers don't get the CSS... That is a problem if operating on mandate of a browser that has loaded a static HTML page. However, CSS inheritance works rather well in most browsers and could, thus, be ported to attributes of the DOM by a JavaScript running in the browser before the accessibility device is addressed. More concretely, the javascript piece would request all inherited properties on any given node and then apply, say, <code>mathintent-mo-mid: &quot;$1 given $2&quot;</code> on all children of <code>&lt;mrow class=&quot;set&quot;&gt;</code> which can become an explicit style attribute which the accessibility tool can then use. The idea is that such a style attribute is interpreted before the general table of default intents and it can <em>fire</em> with more priority than it. This offers a way for authors to create context... and hopefully for authors of the table of default intents to take advantage of it to find more intents in different contexts (math domains, languages...).</p> <p>Changing stylesheet to adjust the purpose might be useful here too: Creating different stylesheets for different recipients and customising stylesheet because of one's stronger knowledge might help the users of accessibility devices obtain a more relevant experience. The change could be in the browser level, at the level of a classroom, at the level of an author, or even at the software level.</p> <p>And if CSS is still not the right selection language for the stylesheets to be authored... there's a lot of generator out there: You can really industrialize the production of the CSS rules that will produce intents to be applied to the very specific category or media.</p> <hr> <h2 id="now-what">Now what?<a class="tdbc-anchor" href="#now-what">#</a></h2> <p>This little &quot;what-if musing&quot; was written to enrich the discussion in the Math community and working group. After a first <a href="https://lists.w3.org/Archives/Public/public-mathml4/2021May/0001.html">announce</a>, David Farmer and Deyan Ginev commented which resulted to the introduction of a property prefix.</p> </content>
</entry>
<entry>
<title>ClipOps 2</title>
<link href="https://mathmlmuses.netlify.app/tryMathML-Copy-CustomTypes/"/>
<updated>2022-09-20T00:07:51+00:00</updated>
<id>https://mathmlmuses.netlify.app/tryMathML-Copy-CustomTypes/</id>
<content type="html"><h3>Idea</h3> <p>The current <a href="https://www.w3.org/TR/2021/WD-clipboard-apis-20210806/">Async clipboard APIs specification</a> is out and allows, after permission, JavaScript pages to invoke copy (write to clipboard) or paste (read from clipboard) when they deem it useful. That is very nice as users start to be aware that permissions is something they could give and trust. As we are on the web, it means that what is copied remains <i>sanitized</i>: a picture is rendered then re-serialized, HTML gets devoided of anything slightly suspicious, the rest is removed.</p> <p>But what is more exciting is that custom types are coming: JavaScript in a page can, for implementing browsers, specify content types that will get transmitted for other apps or other web pages to use.</p> <p>A proposed specification <a href="https://github.com/w3c/clipboard-apis/blob/custom-format-spec/index.bs">pull-request</a> (an amendment) has been made that would allow the content-types to be named with a prefix "web " (web followed by a space, this idea of @annevk makes it impossible to parse a media type out of that) to be put into the clipboard using the same operations. Reveiving web-pages would look for the same pattern and are warned that this is raw content: Depending on the processing, the content must be sanitized (e.g. if put within a web-page, one should avoid to transport trackers or candidate web page attacks).</p> <h3>Application</h3> <p>Here we have a small equation in MathML (from <a href="https://dlmf.nist.gov/14.13">here</a>) and a button to copy it:</p> <p id="simpleExpression" style="text-align:center"><math xmlns="http://www.w3.org/1998/Math/MathML" displaystyle="true"> <mrow> <mrow> <mrow> <msubsup> <mi mathvariant="sans-serif" title="Ferrers function of the first kind">P</mi> <mi title="general degree">&#x3BD;</mi> <mi title="general order">&#x3BC;</mi> </msubsup> <mo>&#x2061;</mo> <mrow> <mo>(</mo> <mrow> <mi title="cosine function">cos</mi> <mo>&#x2061;</mo> <mi title="variable">&#x3B8;</mi> </mrow> <mo>)</mo> </mrow> </mrow> <mo>=</mo> <mrow> <mfrac> <mrow> <msup> <mn>2</mn> <mrow> <mi title="general order">&#x3BC;</mi> <mo>+</mo> <mn>1</mn> </mrow> </msup> <mo>&#x2062;</mo> <msup> <mrow> <mo stretchy="false">(</mo> <mrow> <mi title="sine function">sin</mi> <mo>&#x2061;</mo> <mi title="variable">&#x3B8;</mi> </mrow> <mo stretchy="false">)</mo> </mrow> <mi title="general order">&#x3BC;</mi> </msup> </mrow> <msup> <mi title="the ratio of the circumference of a circle to its diameter">&#x3C0;</mi> <mrow> <mn>1</mn> <mo>/</mo> <mn>2</mn> </mrow> </msup> </mfrac> <mo>&#x2062;</mo> <mrow> <munderover> <mo largeop="true" movablelimits="false" symmetric="true">&#x2211;</mo> <mrow> <mi>k</mi> <mo>=</mo> <mn>0</mn> </mrow> <mi mathvariant="normal">&#x221E;</mi> </munderover> <mrow> <mfrac> <mrow> <mi mathvariant="normal" title="gamma function">&#x393;</mi> <mo>&#x2061;</mo> <mrow> <mo>(</mo> <mrow> <mi title="general degree">&#x3BD;</mi> <mo>+</mo> <mi title="general order">&#x3BC;</mi> <mo>+</mo> <mi>k</mi> <mo>+</mo> <mn>1</mn> </mrow> <mo>)</mo> </mrow> </mrow> <mrow> <mi mathvariant="normal" title="gamma function">&#x393;</mi> <mo>&#x2061;</mo> <mrow> <mo>(</mo> <mrow> <mi title="general degree">&#x3BD;</mi> <mo>+</mo> <mi>k</mi> <mo>+</mo> <mfrac> <mn>3</mn> <mn>2</mn> </mfrac> </mrow> <mo>)</mo> </mrow> </mrow> </mfrac> <mo>&#x2062;</mo> <mfrac> <msub> <mrow> <mo title="Pochhammer&#x2019;s symbol (or shifted factorial)">(</mo> <mrow> <mi title="general order">&#x3BC;</mi> <mo>+</mo> <mfrac> <mn>1</mn> <mn>2</mn> </mfrac> </mrow> <mo title="Pochhammer&#x2019;s symbol (or shifted factorial)">)</mo> </mrow> <mi>k</mi> </msub> <mrow> <mi>k</mi> <mo title="factorial (as in ! n )">!</mo> </mrow> </mfrac> <mo>&#x2062;</mo> <mrow> <mi title="sine function">sin</mi> <mo>&#x2061;</mo> <mrow> <mo>(</mo> <mrow> <mrow> <mo stretchy="false">(</mo> <mrow> <mi title="general degree">&#x3BD;</mi> <mo>+</mo> <mi title="general order">&#x3BC;</mi> <mo>+</mo> <mrow> <mn>2</mn> <mo>&#x2062;</mo> <mi>k</mi> </mrow> <mo>+</mo> <mn>1</mn> </mrow> <mo stretchy="false">)</mo> </mrow> <mo>&#x2062;</mo> <mi title="variable">&#x3B8;</mi> </mrow> <mo>)</mo> </mrow> </mrow> </mrow> </mrow> </mrow> </mrow> </mrow> </math> </p> <p><button id="asyncCopyButton" onclick="fadeButtonIn(); asyncCopy()">copy the expression</button></p> <p>Note that the copy only works on Blink-generation Chromium (or Edge) from version 105 upwards. There, the MathML does only display if you activate "Experimental Web Platform features" from the "chrome://flags/" URL!</p> <p>A you can see in the source, the copy button writes two blobs into the clipboard:</p> <ul> <li><code>web application/mathml+xml</code> the generic type</li> <li><code>web application/mathml-presentation+xml</code> the specific type for MathML-presentation</li> </ul> <h3>Result</h3> <p>Expected: On some platforms and using some browsers the clipboard flavour for MathML should appear so that desktop apps could consume what was copied (e.g. from a web-page of a textbook). We're close to this.</p> <p>The obtained result on my macOS today (2022-09-16) is close to this:</p> <ul> <li><code>com.web.custom.format0</code> containing our MathML source</li> <li><code>com.web.custom.format1</code> containing it too</li> <li><code>com.web.custom.format.map</code> containing a json record as follows:<br> <i>{"application/mathml+xml":"com.web.custom.format0",<br> "application/mathml-presentation+xml":"com.web.custom.format1"}</i></li> </ul> <h3>Conclusion</h3> <p>Web pages will be able to produce rich MathML content using JavaScript. Most probably formula input-editors, formula enrichment or display systems such as MathJax, web-sites with lots of formulæ such as DLMF or wikipedia will all be able to take advantage of this. That looks like a content that is ready to be used by desktop apps, once they know that they have the proper sanitization in place.</p> <p>It also seems that desktop apps can produce this. Well... it seems interoperable!</p> <p>I feel slightly unsafe on the permissions: Can it be that I forget that I allowed access to clipboard? Probably the permissions won't last long. As another drawback this implementation is not yet standardized... which makes it fragile.</p> <p>Optimistic note: Since the code in the page is doing the copy, it is also responsible to support the selection of a portion of the expression to be copied. It is true that this is not as declarative as simple markup but it will let page authors get their say in the selection: e.g. extending a selection of a+b-c+5 from "+b-" to "a+b+c".</p> <h3>Acknowledgement</h3> <p>Thanks @snianu for pushing and developing <a href="https://github.com/w3c/clipboard-apis/blob/custom-format-spec/index.bs">the custom types</a> spec, for @tomayac for making the <a href="https://developer.chrome.com/blog/web-custom-formats-for-the-async-clipboard-api/">helpful blog page</a> and demo at TPAC 2022, for the project <a href="https://fugu-tracker.web.app/">Fugu's streamlining of APIs</a> and for @garykac for keeping on track of the clipboard API spec. </p> <script> async function asyncCopy() { try { const mml = document.getElementById("simpleExpression").innerHTML; const blob = new Blob([mml],{type: 'application/mathml+xml'}); const blob2 = new Blob([mml],{type: 'application/mathml-presentation+xml'}); const clipboardItem = new ClipboardItem({ ['web ' + blob.type]:blob, ['web ' + blob2.type]:blob2, }) await navigator.clipboard.write([clipboardItem]); } catch (e) { console.warn(e); } } function fadeButtonIn() { const elt = document.getElementById("asyncCopyButton") let step = 0, max = 20; let colorize = () => { step++; if(step<10) color = 10*step; else color = 10-(step-10)*10; console.log("color " + color) elt.style.backgroundColor = "rgb(" + color + "," + color + "," + color + "," + color + ")" if(step<=max) window.setTimeout(colorize,100) } window.setTimeout(colorize, 100) } window.addEventListener("load", () => { const elt = document.getElementById("asyncCopyButton") if (typeof(navigator.clipboard.write)=="undefined") { elt.setAttribute("disabled", "true") elt.innerText = " -- function navigator.clipboard.write not found -- " } }) </script> </content>
</entry>
<entry>
<title>ClipOps 1</title>
<link href="https://mathmlmuses.netlify.app/tryMathml-Copy-oldstyle/"/>
<updated>2022-09-20T00:07:51+00:00</updated>
<id>https://mathmlmuses.netlify.app/tryMathml-Copy-oldstyle/</id>
<content type="html"><h3>Basic idea</h3> <p>Any text copied from this page (using the normal copy mechanism) is copied as capitalized plain text (following <a href="https://www.sitepoint.com/clipboard-api/">here</a>) and with an extra flavour of <a href="https://www.w3.org/TR/mathml-media-types/">MathML media type</a> (a simple fraction in presentation MathML).</p> <p>Please look at the source code which has a script element showing the simple process.</p> <h3>Result</h3> <p>Expected: On some platforms and using some browsers the clipboard flavour for MathML should appear so that desktop apps could consume what was copied (e.g. from a web-page of a textbook).</p> <p>The obtained result is in the following pictures:</p> <p>Chromium 108: <img src="https://mathmlmuses.netlify.app/img/copied-mathml-oldstyle-chromium.png"></p> <p>Firefox 105: <img src="https://mathmlmuses.netlify.app/img/copied-mathml-oldstyle-firefox.png"></p> <p>Safari 15.6: <img src="https://mathmlmuses.netlify.app/img/copied-mathml-oldstyle-webkit.png"></p> <h3>Conclusion</h3> <p>It is hard to say if these private formats have a hope to be specified or applicable. Or if they're going to stay at all. Maybe this is the reason why softwares such as Word prefer to do content-sniffing, detecting MathML in the plain-text.</p> <p>I must say... this shows well that the current formula copy and paste does not work well, as you can see in <a href="https://www.w3.org/2022/09/TPAC/demos/mathml-formulae.html">this video</a>.</p> <script> window.addEventListener("load", () => { document.body.addEventListener('copy', copyHandler); // cut or copy event handler async function copyHandler(e) { const selection = document.getSelection(); // send uppercase text to clipboard e.clipboardData.setData( 'text/plain', selection.toString().toUpperCase() ); e.clipboardData.setData('application/mathml+xml', '<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>'); //e.clipboardData.setData('text/html', '<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>'); // stop default cut/copy e.preventDefault(); } }); async function asyncCopy() { try { const blob = new Blob(['<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>'],{type: 'text/html'}); const blob2 = new Blob(['<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>'], {type: 'application/mathml+xml'}) const clipboardItem = new ClipboardItem({ ['web application/mathml+xml']:blob2, ['text/html']: blob, //['web application/mathml+xml']:'<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>', //['web text/html']: '<math><mfrac><mn>3</mn><mn>5</mn></mfrac></math>' }) await navigator.clipboard.write([clipboardItem]); } catch (e) { console.warn(e); } } </script> </content>
</entry>
</feed>