diff --git a/src/main/java/org/olat/core/gui/render/StringOutput.java b/src/main/java/org/olat/core/gui/render/StringOutput.java
index 412d7433c221ca65b2fb9712038445fd086ff987..0118b2ea155809d4f10fa95160b36813248b0592 100644
--- a/src/main/java/org/olat/core/gui/render/StringOutput.java
+++ b/src/main/java/org/olat/core/gui/render/StringOutput.java
@@ -207,6 +207,10 @@ public class StringOutput extends Writer {
 		return sb.length();
 	}
 	
+	public boolean contains(String str) {
+		return sb.indexOf(str) >= 0;
+	}
+	
 	public Reader getReader() {
 		return new StringOutputReader();
 	}
diff --git a/src/main/java/org/olat/core/util/Formatter.java b/src/main/java/org/olat/core/util/Formatter.java
index a4356f856ae82b665312ec876973eaab32a45142..28b0ad2caaa5fb74cc8df3be14ed5afbbce4f748 100644
--- a/src/main/java/org/olat/core/util/Formatter.java
+++ b/src/main/java/org/olat/core/util/Formatter.java
@@ -68,9 +68,6 @@ public class Formatter {
 
 	private static final Map<Locale,Formatter> localToFormatterMap = new HashMap<>();
 
-	// Pattern to find math classes
-	private static final Pattern classMathPattern = Pattern.compile(".*class[ ]*=[ ]*(math|(['\"])([a-zA-Z0-9_\\- ]* )*math( [a-zA-Z0-9_\\- ]*)*\\2).*");
-	
 	private final Locale locale;
 	private final DateFormat shortDateFormat;
 	private final DateFormat longDateFormat;
diff --git a/src/main/java/org/olat/core/util/WebappHelper.java b/src/main/java/org/olat/core/util/WebappHelper.java
index 9b9431688e968da772d580a15e8ac3b1ab8ff70a..0aa920f952ac8ac8497ac97dbcce21185660c0c6 100644
--- a/src/main/java/org/olat/core/util/WebappHelper.java
+++ b/src/main/java/org/olat/core/util/WebappHelper.java
@@ -77,6 +77,8 @@ public class WebappHelper implements Initializable, Destroyable, ServletContextA
 	
 	private static String mathJaxCdn;
 	private static String mathJaxConfig;
+	private static boolean mathJaxMarkers;
+	
 	private static String mobileContext;
 	
 	/** need to set this at least once before the actual request, since we cannot extract it from the servletContext, 
@@ -312,6 +314,14 @@ public class WebappHelper implements Initializable, Destroyable, ServletContextA
 	public void setMathJaxConfig(String mathJaxConfig) {
 		WebappHelper.mathJaxConfig = mathJaxConfig;
 	}
+	
+	public static boolean isMathJaxMarkers() {
+		return mathJaxMarkers;
+	}
+	
+	public void setMathJaxMarkers(boolean mathJaxMarkers) {
+		WebappHelper.mathJaxMarkers = mathJaxMarkers;
+	}
 
 	public void setFullPathToSrc(String fullPathToSrc) {
 		File path = new File(fullPathToSrc);
diff --git a/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml b/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml
index 8574eb3e3131b43fa9d13c5e6e2011f87862151b..32f47349095d8f06a2a97f6a4bb889861abff38c 100644
--- a/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml
+++ b/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml
@@ -49,6 +49,7 @@
 		<property name="mobileContext" value="${mobile.context}" />
 		<property name="mathJaxCdn" value="${mathjax.cdn}"/>
 		<property name="mathJaxConfig" value="${mathjax.config}"/>
+		<property name="mathJaxMarkers" value="${mathjax.markers}"/>
 	</bean>
 
 	<bean id="org.olat.core.helpers.Settings" class="org.olat.core.helpers.Settings" depends-on="org.olat.core.util.WebappHelper">
diff --git a/src/main/java/org/olat/core/util/filter/impl/NekoHTMLMathScanner.java b/src/main/java/org/olat/core/util/filter/impl/NekoHTMLMathScanner.java
index 68c23ea336c9868a747ec535a1a51de559566c6f..f2a0ef1aa36f330d9d47813e23cc494697fc6619 100644
--- a/src/main/java/org/olat/core/util/filter/impl/NekoHTMLMathScanner.java
+++ b/src/main/java/org/olat/core/util/filter/impl/NekoHTMLMathScanner.java
@@ -24,8 +24,10 @@ import java.io.StringReader;
 import org.cyberneko.html.parsers.SAXParser;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.core.util.WebappHelper;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
 /**
@@ -80,5 +82,15 @@ public class NekoHTMLMathScanner {
 				}
 			}
 		}
+
+		@Override
+		public void characters(char[] ch, int start, int length) throws SAXException {
+			if(!mathFound && WebappHelper.isMathJaxMarkers()) {
+				String content = new String(ch, start, length);
+				if(content.contains("\\(") || content.contains("\\[") || content.contains("$$")) {
+					mathFound = true;
+				}
+			}
+		}
 	}
 }
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentItemComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentItemComponentRenderer.java
index 2cfa1a044ce1700da89288305387c951170f3309..cf61e54aaa4daab522cd8f9a710d9cb146d2bb37 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentItemComponentRenderer.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentItemComponentRenderer.java
@@ -30,7 +30,9 @@ import org.olat.core.gui.translator.Translator;
 import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.core.util.Formatter;
 import org.olat.core.util.StringHelper;
+import org.olat.core.util.WebappHelper;
 import org.olat.ims.qti21.AssessmentTestSession;
 import org.olat.ims.qti21.model.audit.CandidateEvent;
 import org.olat.ims.qti21.model.audit.CandidateItemEventType;
@@ -90,6 +92,11 @@ public class AssessmentItemComponentRenderer extends AssessmentObjectComponentRe
             /* Render event */
             AssessmentRenderer renderHints = new AssessmentRenderer(renderer);
             renderItemEvent(renderHints, sb, cmp, latestEvent, itemSessionState, ubu, translator);
+            
+            if(renderHints.isMathJax()
+            		|| (WebappHelper.isMathJaxMarkers() && ((sb.contains("\\(") || sb.contains("\\[") || sb.contains("&&"))))) {
+				sb.append(Formatter.elementLatexFormattingScript("itemBody"));
+			}
         }
 		
 		sb.append("</div>");
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java
index d56f17be9db0aa7b57e5db10247cf2f657b0b695..0a5ca8b2f956858945463e5675ab2557bcd5f13f 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java
@@ -83,7 +83,6 @@ import org.olat.core.helpers.Settings;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.CodeHelper;
-import org.olat.core.util.Formatter;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.ims.qti21.QTI21Constants;
@@ -472,27 +471,20 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent
 			}
 			case RubricBlock.QTI_CLASS_NAME: break; //never rendered automatically
 			case Math.QTI_CLASS_NAME: {
-				String domid = "mw_" + CodeHelper.getRAMUniqueID();
-				sb.append("<div id=\"").append(domid).append("\">");
+				sb.append("<div>");
 				renderMath(renderer, sb, component, resolvedAssessmentItem, itemSessionState, (Math)block);
-				sb.append("</div>")
-				  .append(Formatter.elementLatexFormattingScript(domid));
+				sb.append("</div>");
+				renderer.setMathJax(true);
 				break;
 			}
 			case Div.QTI_CLASS_NAME: {
-				String domid = null;
 				if (containsClass(block, "math")) {
-					domid = "mw_" + CodeHelper.getRAMUniqueID();
-					sb.append("<div id=\"").append(domid).append("\">");
+					renderer.setMathJax(true);
 				}
 				renderStartHtmlTag(sb, component, resolvedAssessmentItem, block, null);
 				((Div)block).getFlows().forEach((flow)
 						-> renderFlow(renderer, sb, component, resolvedAssessmentItem, itemSessionState, flow, ubu, translator));
 				renderEndTag(sb, block);
-				if (domid != null) {
-					sb.append("</div>")
-					  .append(Formatter.elementLatexFormattingScript(domid));
-				}
 				break;
 			}
 			case Ul.QTI_CLASS_NAME:
@@ -688,11 +680,10 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent
 				break;
 			}
 			case Math.QTI_CLASS_NAME: {
-				String domid = "mw_" + CodeHelper.getRAMUniqueID();
-				sb.append("<span id=\"").append(domid).append("\">");
+				sb.append("<span>");
 				renderMath(renderer, sb, component, resolvedAssessmentItem, itemSessionState, (Math)inline);
-				sb.append("</span>")
-				  .append(Formatter.elementLatexFormattingScript(domid));
+				sb.append("</span>");
+				renderer.setMathJax(true);
 				break;
 			}
 			case Img.QTI_CLASS_NAME: {
@@ -730,22 +721,12 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent
 	protected final void renderSpan(AssessmentRenderer renderer, StringOutput sb, Span span, AssessmentObjectComponent component,
 			ResolvedAssessmentItem resolvedAssessmentItem, ItemSessionState itemSessionState, URLBuilder ubu, Translator translator) {
 		if (containsClass(span,"math")) {
-			String domid = "mw_" + CodeHelper.getRAMUniqueID();
-			sb.append("<span id=\"").append(domid).append("\">");
-			
-			renderStartHtmlTag(sb, component, resolvedAssessmentItem, span, null);
-			span.getInlines().forEach((child)
-					-> renderInline(renderer, sb, component, resolvedAssessmentItem, itemSessionState, child, ubu, translator));
-			renderEndTag(sb, span);
-			
-			sb.append("</span>")
-			  .append(Formatter.elementLatexFormattingScript(domid));
-		} else {
-			renderStartHtmlTag(sb, component, resolvedAssessmentItem, span, null);
-			span.getInlines().forEach((child)
-					-> renderInline(renderer, sb, component, resolvedAssessmentItem, itemSessionState, child, ubu, translator));
-			renderEndTag(sb, span);
+			renderer.setMathJax(true);
 		}
+		renderStartHtmlTag(sb, component, resolvedAssessmentItem, span, null);
+		span.getInlines().forEach((child)
+			-> renderInline(renderer, sb, component, resolvedAssessmentItem, itemSessionState, child, ubu, translator));
+		renderEndTag(sb, span);
 	}
 	
 	protected final void renderA(AssessmentRenderer renderer, StringOutput sb, A a, AssessmentObjectComponent component,
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentRenderer.java
index 5e773414c4cda504eb35662abf276596f60427fc..c02ac5c605e0171dd6923b787970f537eff160f4 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentRenderer.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentRenderer.java
@@ -32,6 +32,7 @@ import org.olat.core.gui.render.URLBuilder;
 public class AssessmentRenderer {
 
 	private Renderer renderer;
+	private boolean mathJax;
 	private boolean mathXsltDisabled;
 	private boolean solutionMode;
 	private boolean reviewMode;
@@ -145,6 +146,14 @@ public class AssessmentRenderer {
 		this.showTitles = showTitles;
 	}
 
+	public boolean isMathJax() {
+		return mathJax;
+	}
+
+	public void setMathJax(boolean mathJax) {
+		this.mathJax = mathJax;
+	}
+
 	public void setRenderer(Renderer renderer) {
 		this.renderer = renderer;
 	}
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponentRenderer.java
index df888483943013e99fd4004ca158bb35e216fb23..3c48cf5ca2b6ae1ce11c3e26183d5601fdacdc04 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponentRenderer.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponentRenderer.java
@@ -51,7 +51,9 @@ import org.olat.core.gui.translator.Translator;
 import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.core.util.Formatter;
 import org.olat.core.util.StringHelper;
+import org.olat.core.util.WebappHelper;
 import org.olat.course.assessment.AssessmentHelper;
 import org.olat.ims.qti21.AssessmentTestSession;
 import org.olat.ims.qti21.QTI21Constants;
@@ -127,6 +129,11 @@ public class AssessmentTestComponentRenderer extends AssessmentObjectComponentRe
 				/* Render event */
 				AssessmentRenderer renderHints = new AssessmentRenderer(renderer);
 				renderTestEvent(testSessionController, renderHints, sb, cmp, ubu, translator);
+				
+				if(renderHints.isMathJax()
+	            		|| (WebappHelper.isMathJaxMarkers() && ((sb.contains("\\(") || sb.contains("\\[") || sb.contains("&&"))))) {
+					sb.append(Formatter.elementLatexFormattingScript("itemBody"));
+				}
 			}
 		}
 	}
diff --git a/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java b/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java
index 2b78d36222d7562c4e9e74cf5ee1874d302dfaa8..cdf4682d6d141ec2844eb8cf8d463912aa11b61a 100644
--- a/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java
+++ b/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java
@@ -55,14 +55,6 @@ import org.olat.core.util.Formatter;
  */
 public class WikiMarkupRenderer extends DefaultComponentRenderer {
 
-	/**
-	 * @see org.olat.core.gui.components.ComponentRenderer#render(org.olat.core.gui.render.Renderer,
-	 *      org.olat.core.gui.render.StringOutput,
-	 *      org.olat.core.gui.components.Component,
-	 *      org.olat.core.gui.render.URLBuilder,
-	 *      org.olat.core.gui.translator.Translator,
-	 *      org.olat.core.gui.render.RenderResult, java.lang.String[])
-	 */
 	@Override
 	public void render(Renderer renderer, StringOutput sb, Component source, URLBuilder ubu, Translator translator,
 			RenderResult renderResult, String[] args) {
@@ -97,9 +89,9 @@ public class WikiMarkupRenderer extends DefaultComponentRenderer {
 				String targetUrl = " onclick=\"o_XHREvent(jQuery(this).attr('href'),false,true); return false;\"";
 				input.setURLTarget(targetUrl);
 			}
-			sb.append("<div style=\"min-height:"+ wikiComp.getMinHeight() +"px\" id=\"");
-			sb.append(uniqueId);
-			sb.append("\">");
+			sb.append("<div style=\"min-height:").append(wikiComp.getMinHeight()).append("px\" id=\"")
+			  .append(uniqueId)
+			  .append("\">");
 		
 			JFlexParser parser = new JFlexParser(input);
 			parsedDoc = parser.parseHTML(wikiComp.getWikiContent());
@@ -109,12 +101,11 @@ public class WikiMarkupRenderer extends DefaultComponentRenderer {
 			throw new OLATRuntimeException(this.getClass(), "error while rendering wiki page with content:"+ wikiComp.getWikiContent(), e);
 		}
 		// Use global js math formatter for latex formulas
-		sb.append(Formatter.formatLatexFormulas(parsedDoc.getContent()));
-		sb.append("</div>");
+		sb.append(Formatter.formatLatexFormulas(parsedDoc.getContent()))
+		  .append("</div>");
 		//set targets of media, image and external links to target "_blank" 
-		sb.append("<script type=\"text/javascript\">/* <![CDATA[ */ ");
-		String instanceUrl = Settings.getServerContextPathURI();
-		sb.append("changeAnchorTargets('").append(uniqueId).append("','").append(instanceUrl).append("');");
-		sb.append("/* ]]> */</script>");
+		sb.append("<script type=\"text/javascript\">/* <![CDATA[ */ ")
+		  .append("changeAnchorTargets('").append(uniqueId).append("','").append(Settings.getServerContextPathURI()).append("');")
+		  .append("/* ]]> */</script>");
 	}
 }
diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties
index dcf02261fa2a1f0e44b2d7e05a824d2389029bad..3e6c1604b599cde59871d8cca4e1a7af7314cf67 100644
--- a/src/main/resources/serviceconfig/olat.properties
+++ b/src/main/resources/serviceconfig/olat.properties
@@ -517,6 +517,8 @@ jmx.rmi.port=3000
 
 mathjax.cdn=//mathjax.openolat.org/mathjax/2.7-latest/
 mathjax.config=TeX-AMS-MML_HTMLorMML
+# find \( \), \[ \], $$ to trigger MathJax rendering
+mathjax.markers=true
 
 ########################################################################
 # Database settings