Skip to content

Commit 66a9033

Browse files
authored
allow degree symbol as unit (#285)
1 parent f7e48d2 commit 66a9033

File tree

6 files changed

+39
-8
lines changed

6 files changed

+39
-8
lines changed

classes/local/evaluator.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,8 @@ private function set_variable_to_value(token $vartoken, token $value, $definingr
365365
$basename = strstr($basename, '[', true);
366366
}
367367

368-
// We do not allow Ω and µ in variable names.
369-
$isunit = preg_match('/[\x{00B5}\x{03BC}\x{03A9}\x{2126}]/u', $basename);
368+
// We do not allow °, Ω and µ in variable names.
369+
$isunit = preg_match('/[°\x{00B5}\x{03BC}\x{03A9}\x{2126}]/u', $basename);
370370
if ($isunit) {
371371
$this->die(get_string('error_invalidvarname', 'qtype_formulas', $basename), $value);
372372
}

classes/local/lexer.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ private function read_next_token(): ?token {
109109
}
110110
// A letter indicates the start of an identifier, i. e. a variable or function name.
111111
// We also accept U+00B5 (MICRO SIGN), U+03BC (GREEK SMALL MU), U+2126 (OHM) and
112-
// U+03A9 (GREEK CAPITAL OMEGA) for units.
113-
if (preg_match('/[_A-Za-z\x{00B5}\x{03BC}\x{03A9}\x{2126}]/u', $currentchar)) {
112+
// U+03A9 (GREEK CAPITAL OMEGA) for units. And we allow the degree symbol ° as well.
113+
if (preg_match('/[_A-Za-z°\x{00B5}\x{03BC}\x{03A9}\x{2126}]/u', $currentchar)) {
114114
return $this->read_identifier();
115115
}
116116
// Unless we are in the middle of a ternary operator, we treat : as a RANGE_SEPARATOR.
@@ -426,10 +426,11 @@ private function read_identifier(): token {
426426
while ($currentchar !== input_stream::EOF) {
427427
$nextchar = $this->inputstream->peek();
428428
// Identifiers may contain letters, digits or underscores. Also, we will accept the
429-
// µ and Ω symbols, because they may appear in units. We don't want to throw lexing
430-
// errors while reading them. Note that we explicitly include U+00B5 (MICRO SIGN),
431-
// U+03BC (GREEK SMALL MU), U+2126 (OHM) and U+03A9 (GREEK CAPITAL OMEGA).
432-
if (!preg_match('/[A-Za-z0-9_\x{00B5}\x{03BC}\x{03A9}\x{2126}]/u', $nextchar)) {
429+
// µ and Ω symbols, because they may appear in units. The same is true for the degree °
430+
// symbol. We don't want to throw lexing errors while reading them. Note that we
431+
// explicitly include U+00B5 (MICRO SIGN), U+03BC (GREEK SMALL MU), U+2126 (OHM) and
432+
// U+03A9 (GREEK CAPITAL OMEGA).
433+
if (!preg_match('/[A-Za-z°0-9_\x{00B5}\x{03BC}\x{03A9}\x{2126}]/u', $nextchar)) {
433434
break;
434435
}
435436
$currentchar = $this->inputstream->read();

tests/answer_parser_test.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ public static function provide_numbers_and_units(): array {
314314
'MICRO SIGN' => [['1', 'µs'], '1 µs'],
315315
'percent with space' => [['5', '%'], '5 %'],
316316
'percent without space' => [['5', '%'], '5%'],
317+
'degree with space' => [['5', '°'], '5 °'],
318+
'degree without space' => [['5', '°'], ''],
317319

318320
[['.3', ''], '.3'],
319321
[['3.1', ''], '3.1'],

tests/evaluator_test.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,6 +1842,18 @@ public static function provide_invalid_assignments(): array {
18421842
'Invalid variable name: kΩ.',
18431843
'kΩ = 2',
18441844
],
1845+
'invalid variable, degree alone' => [
1846+
'Invalid variable name: °.',
1847+
'° = 2',
1848+
],
1849+
'invalid variable, degree at start' => [
1850+
'Invalid variable name: °x.',
1851+
'°x = 2',
1852+
],
1853+
'invalid variable, degree in name' => [
1854+
'Invalid variable name: k°.',
1855+
'k° = 2',
1856+
],
18451857
'invalid assignment with % at end' => [
18461858
"Syntax error: unexpected end of expression after '%'.",
18471859
'a = 2 %',

tests/questiontype_test.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ public static function provide_single_part_data_for_form_validation(): array {
312312
[[], ['answer' => [0 => '\sin(20)']]],
313313
[[], ['answer' => [0 => '[1, 2]']]],
314314
[[], ['answer' => [0 => '0']]],
315+
[[], ['answer' => [0 => '5'], 'postunit' => [0 => '°']]],
315316
[[], ['answer' => [0 => '5'], 'postunit' => [0 => '%']]],
316317
[[], ['answer' => [0 => '1'], 'postunit' => [0 => 'Ω']]],
317318
[[], ['answer' => [0 => '1'], 'postunit' => [0 => 'µs']]],

tests/walkthrough_adaptive_test.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,21 @@ public function test_combined_field_with_percent(): void {
986986
$this->check_current_mark(1);
987987
}
988988

989+
public function test_combined_field_with_degree(): void {
990+
// Create a question.
991+
$q = $this->get_test_formulas_question('testsinglenumunit');
992+
$q->parts[0]->answer = '5';
993+
$q->parts[0]->postunit = '°';
994+
995+
// Start an attempt and submit various correct answers.
996+
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
997+
$this->process_submission(['0_' => '5 °', '-submit' => 1]);
998+
$this->check_current_mark(1);
999+
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
1000+
$this->process_submission(['0_' => '', '-submit' => 1]);
1001+
$this->check_current_mark(1);
1002+
}
1003+
9891004
public function test_combined_field_with_ohm(): void {
9901005
// Create a question.
9911006
$q = $this->get_test_formulas_question('testsinglenumunit');

0 commit comments

Comments
 (0)