From 8dc24fc5a5ee592839466fde108ad1c5d19995c1 Mon Sep 17 00:00:00 2001 From: Matti Harjula Date: Fri, 26 Jun 2026 09:49:57 +0300 Subject: [PATCH] Related to behaviour observed in issue #1777. Modifies inline-CASText simplification so that "flat" things are not simplified in advance, to ensure that the logic doing `{@...@}` injections of inline-CASText does not consider them as "strings" and apply extra SMLT on them. This solution does not cover the use of `castext_concat()` or `castext_simplify()` on inline-CASText fragments, those can still turn "flat" content to "strings" and lead to extra SMLT that might affect areas that should nto be affected by SMLT. Should you use those and the result needs to be protected from overt SMLT application, you can use the old `[[castext evaluated="..."/]]`-block which was the predeccor of the `{@...@}` injection shorthand. It will do a pure injection without any risk of extra SMLT. --- stack/cas/parsingrules/601_castext.filter.php | 7 +++++++ stack/cas/parsingrules/602_castext_simplifier.filter.php | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/stack/cas/parsingrules/601_castext.filter.php b/stack/cas/parsingrules/601_castext.filter.php index ba6a45a012a..e1ca512deb7 100644 --- a/stack/cas/parsingrules/601_castext.filter.php +++ b/stack/cas/parsingrules/601_castext.filter.php @@ -91,6 +91,13 @@ public function filter(MP_Node $ast, array &$errors, array &$answernotes, stack_ $compiled = $compiled->statement; } $compiled->position['castext'] = true; + if ($compiled instanceof MP_String) { + // An inline-CASText fragment cannot be flat, as injections of such could not be distinguished + // from string injections. For this reason we tag it with a marker to stop simplification. + // And make it non flat if it already is. + $compiled = new MP_List([new MP_String('%root'), $compiled]); + } + $compiled->position['inline-castext'] = true; $node->parentnode->replace($node, $compiled); return false; } else if ($node->name instanceof MP_Identifier && $node->name->value === 'castext_concat') { diff --git a/stack/cas/parsingrules/602_castext_simplifier.filter.php b/stack/cas/parsingrules/602_castext_simplifier.filter.php index 892d9ecacaa..f55572d6408 100644 --- a/stack/cas/parsingrules/602_castext_simplifier.filter.php +++ b/stack/cas/parsingrules/602_castext_simplifier.filter.php @@ -237,8 +237,8 @@ public function filter(MP_Node $ast, array &$errors, array &$answernotes, stack_ $node->items[0]->value === 'demoodle' || $node->items[0]->value === 'htmlformat') ) { - if ($node->items[0]->value === '%root' && count($node->items) === 2 && $node->items[1] instanceof MP_String) { - // A concatenation of a single string, can be removed. If %root. + if ($node->items[0]->value === '%root' && count($node->items) === 2 && $node->items[1] instanceof MP_String && !(isset($node->position['inline-castext']) && $node->position['inline-castext'])) { + // A concatenation of a single string, can be removed. If %root and not inline-CASText. $node->parentnode->replace($node, $node->items[1]); return false; }