Änderungen von Dokument MathJaxMacro

Zuletzt geändert von xwikiadmin am 2025/01/07 11:38

Von Version 1.1
bearbeitet von xwikiadmin
am 2024/06/24 14:35
Änderungskommentar: Install extension [org.xwiki.contrib.mathjax:macro-mathjax-ui/1.0.5]
Auf Version 2.1
bearbeitet von xwikiadmin
am 2025/01/07 11:38
Änderungskommentar: Install extension [org.xwiki.contrib.mathjax:macro-mathjax-ui/1.1.7]

Zusammenfassung

Details

XWiki.JavaScriptExtension[0]
Code
... ... @@ -1,35 +1,126 @@
1 -// Configure MathJax before it's loaded
2 -// See http://docs.mathjax.org/en/latest/configuration.html
3 -window.MathJax = {
4 - displayAlign: "left",
5 - displayIndent: "2em",
6 - elements: document.getElementsByClassName("xwiki-mathjax"),
7 - TeX: { equationNumbers: { autoNumber: "AMS" } }
8 -};
1 +define('setupMathjax', ['jquery'], function($) {
2 + // See http://docs.mathjax.org/en/latest/configuration.html
3 + // In order to avoid https://github.com/mathjax/MathJax/issues/2999, the 'elements' configuration was removed. Right
4 + // now, a ignoreHtmlClass was added to the body, in order to force Mathjax to typeset only elements that have the
5 + // the processHtmlClass (i.e. xwiki-mathjax).
6 + window.MathJax = {
7 + chtml: {
8 + displayAlign: "left",
9 + displayIndent: "2em"
10 + },
11 + startup: {
12 + pageReady() {
13 + document.body.classList.add('mathjax-ignore');
14 + if ($('#renderedChanges').length > 0) {
15 + return typesetInRenderedDiffViewPromise().then(() => clearAndTypesetPromise());
16 + } else {
17 + // Backup the formula source code in a data attribute and cleanup formulas that are already rendered.
18 + prepareFormulas();
19 + // Let MathJax handle typeset.
20 + return MathJax.startup.defaultPageReady();
21 + }
22 + },
23 + typeset: $('#renderedChanges').length <= 0
24 + },
25 + tex: {
26 + tags: "ams",
27 + autoload: {
28 + color: [],
29 + colorv2: ['color']
30 + },
31 + packages: {'[+]': ['noerrors']}
32 + },
33 + options: {
34 + ignoreHtmlClass: 'mathjax-ignore',
35 + processHtmlClass: 'xwiki-mathjax'
36 + },
37 + loader: {
38 + load: ['[tex]/noerrors']
39 + }
40 + };
9 9  
10 -// Load MathJax from its WebJar.
11 -require(["$services.webjars.url('org.webjars.npm:mathjax', 'MathJax.js', { 'config' : 'TeX-AMS_HTML' })"], function() {
12 - // The MathJax library adds some DIVs at the start of the BODY element (in order to display messages) and this leads
13 - // to empty pages when exporting to PDF even when no message is displayed because they are not hidden (height: 1px).
14 - // The best practice is to inject such DIVs at the end of the BODY element, which this clean-up function does.
15 - const cleanUp = function() {
16 - // Move the hidden MathJax containers at the end of the BODY element.
17 - const containers = document.querySelectorAll('body > div > #MathJax_Hidden, body > div > #MathJax_SVG_Hidden');
18 - containers.forEach(function(container) {
19 - document.body.appendChild(container.parentNode);
42 + function prepareFormulas() {
43 + // Go through all the MathJax formulas we can find in the page.
44 + document.querySelectorAll('.xwiki-mathjax').forEach(mathjaxWrapper => {
45 + // Check if the MathJax formula source code was already backed up.
46 + if (mathjaxWrapper.hasAttribute('data-xwiki-mathjax')) {
47 + // Force a new rendering by resetting the wrapper text content using the backed up formula source.
48 + mathjaxWrapper.textContent = mathjaxWrapper.getAttribute('data-xwiki-mathjax');
49 + } else {
50 + // Backup the formula source code in order to be able to force a re-rendering.
51 + mathjaxWrapper.setAttribute('data-xwiki-mathjax', mathjaxWrapper.textContent);
52 + }
20 20   });
54 + }
55 +
56 + /**
57 + * Reset the tex labels, since re-typesetting might create duplicate labels, and perform an asynchronous typesetting.
58 + * See https://docs.mathjax.org/en/latest/web/typeset.html#handling-asynchronous-typesetting.
59 + */
60 + var clearAndTypesetPromise = function(elems) {
61 + let typesetPromise;
62 + MathJax.texReset();
63 + // Using the elements parameter could lead to bugs https://github.com/mathjax/MathJax/issues/2999, so for now
64 + // typesetting specific elements should be used only if equations numbering does not count. For example, this is
65 + // used for typesetting in rendered diff view, since only one math element is send at a time.
66 + typesetPromise = MathJax.typesetPromise(elems);
67 + typesetPromise.catch((err) => console.log('Typeset failed: ' + err.message));
68 + return typesetPromise;
21 21   };
22 22  
71 + /**
72 + * Since the same macro will be displayed twice in a rendered diff view, we typeset each one individually in order to
73 + * avoid errors from duplicate labels. This will produce some inconsistences with the displayed equation numbers,
74 + * meaning that each macro will start counting from 1 and anchor ids will be duplicated.
75 + */
76 + var typesetInRenderedDiffViewPromise = function() {
77 + let promise = Promise.resolve();
78 + $('#renderedChanges .xwiki-mathjax').each((i, el) => {
79 + if ($(el).find('mjx-container').length > 0) {
80 + return;
81 + }
82 + // Mathjax doesn't typesets math code mixed with html content.
83 + el.innerHTML = el.textContent;
84 + promise = promise.then(() => clearAndTypesetPromise([el]));
85 + });
86 +
87 + return promise;
88 + };
89 +
90 + return {
91 + clearAndTypesetPromise: clearAndTypesetPromise,
92 + typesetInRenderedDiffViewPromise: typesetInRenderedDiffViewPromise
93 + };
94 +});
95 +
96 +// Configure MathJax before loading it.
97 +require.config({
98 + paths: {
99 + 'mathjax': "$services.webjars.url('org.webjars.npm:mathjax', 'es5/tex-chtml.js')"
100 + },
101 + shim: {
102 + 'mathjax': ['setupMathjax']
103 + }
104 +});
105 +
106 +require(["jquery", 'mathjax', 'setupMathjax'], function($, math, setup) {
107 + // See https://docs.mathjax.org/en/latest/web/configuration.html#performing-actions-after-typesetting.
108 + var promise = MathJax.startup.promise;
23 23   // Delay the page ready until all formulas are generated, if supported.
24 24   if (require.defined('xwiki-page-ready')) {
25 25   require(['xwiki-page-ready'], function(pageReady) {
26 - pageReady.delayPageReady(new Promise(function(resolve, reject) {
27 - // See http://docs.mathjax.org/en/v2.7-latest/advanced/queues.html#the-mathjax-processing-queue
28 - MathJax.Hub.Queue(function() {
29 - cleanUp();
30 - resolve();
31 - });
32 - }), 'MathJax');
112 + pageReady.delayPageReady(promise, 'MathJax');
33 33   });
34 34   }
115 +
116 + $(document).on('xwiki:dom:updated', function(e, data) {
117 + // The typeset should be done only on modified mathjax elements, instead of doing it on the whole page, after this
118 + // bug is fixed https://github.com/mathjax/MathJax/issues/2999 .
119 + if ($('#renderedChanges').length > 0) {
120 + promise.then(() => setup.typesetInRenderedDiffViewPromise())
121 + .then(() => setup.clearAndTypesetPromise());
122 + } else {
123 + promise.then(() => setup.clearAndTypesetPromise());
124 + }
125 + });
35 35  });
XWiki.WikiMacroClass[0]
Makro-Code
... ... @@ -1,14 +1,16 @@
1 1  {{velocity}}
2 -$xwiki.jsx.use('Macros.MathJaxMacro')
2 +$xwiki.jsx.use('Macros.MathJaxMacro', {'wysiwyg': true})
3 3  
4 4  {{html clean='true'}}
5 5  #if ($wikimacro.context.isInline())
6 -<span class="xwiki-mathjax">
6 +<span class="xwiki-mathjax">##
7 7  #else
8 8  <div class="xwiki-mathjax">
9 9  #end
10 -## Replace { with the HTML entity to prevent any user-provided content from closing the HTML macro.
11 -$stringtool.replace($xcontext.macro.content, "{", "&#123;")
10 +## XML-escape the macro content to avoid HTML content such as javascript from being executed (it also escapes the
11 +## "{" character and thus prevents any user-provided content from closing the HTML macro).
12 +## Note: The HTML macro is used only to properly wrap the content in SPAN and DIV which is hard to do with wiki syntax
13 +$escapetool.xml($xcontext.macro.content)##
12 12  #if ($wikimacro.context.isInline())
13 13  </span>
14 14  #else
Standardkategorie
... ... @@ -1,1 +1,1 @@
1 -content
1 +Content
Makrobeschreibung
... ... @@ -1,0 +1,1 @@
1 +Enter content supported by the MathJax javascript engine.