From 3abcf4b5a3bc8e47f914d4831eac90ee0252ed2d Mon Sep 17 00:00:00 2001 From: Andre Herbst Date: 2024年4月21日 21:58:21 +0200 Subject: [PATCH] fix: enforce full line to match when reference regex has the form ^...$ --- _data/localization.json | 7 ++++++- _layouts/tutorial.html | 4 ++++ css/playfield.css | 3 +++ de/05-02.html | 4 ++-- en/05-02.html | 4 ++-- js/playfield.js | 44 ++++++++++++++++++++++++++++++++--------- 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/_data/localization.json b/_data/localization.json index 2ccac6c..cb35072 100644 --- a/_data/localization.json +++ b/_data/localization.json @@ -89,7 +89,12 @@ "de": "✓ gefunden", "sv": "✓ matchade", "pt-br": "✓ corresponde" - + }, + "matchedIncompletely": { + "en": "(✓) matched, but whole line should match", + "de": "(✓) gefunden, aber die ganze Zeile soll passen", + "sv": "(✓) matchade, men hela raden ska matcha", + "pt-br": "(✓) corresponde, mas toda a linha deve corresponder" }, "shouldNotMatch": { "en": "✓ matched, but should not match", diff --git a/_layouts/tutorial.html b/_layouts/tutorial.html index 1afeabb..8ed3a5c 100644 --- a/_layouts/tutorial.html +++ b/_layouts/tutorial.html @@ -35,6 +35,10 @@ content: "{{ site.data.localization.hint.hidden[page.lang] }}"; } + .playfield.verbose .incompletematch.ok:after { + content: "{{ site.data.localization.match.matchedIncompletely[page.lang] }}"; + } + .playfield.verbose .match.ok:after { content: "{{ site.data.localization.match.matched[page.lang] }}"; } diff --git a/css/playfield.css b/css/playfield.css index 9354089..27984ba 100644 --- a/css/playfield.css +++ b/css/playfield.css @@ -51,6 +51,9 @@ .playfield .nomatch { } +.playfield .incompletematch.ok { + background-color: {{ site.data.colors.fails }}; +} .playfield .nomatch.ok { background-color: {{ site.data.colors.fails }}; } diff --git a/de/05-02.html b/de/05-02.html index 26aef23..148bdab 100644 --- a/de/05-02.html +++ b/de/05-02.html @@ -5,8 +5,8 @@ Der nächste Ausdruck soll die Zahlen 20 bis 29 finden aber er tut es nicht. Magst du ihn ändern, dass er nur die Zahlen zwischen 20 und 29 erkennt?

-
- +
+
  • 12
  • diff --git a/en/05-02.html b/en/05-02.html index 47cef90..2a665b3 100644 --- a/en/05-02.html +++ b/en/05-02.html @@ -5,8 +5,8 @@ The following expression shall find the numbers 20 to 29 but it has mistakes. Would you like to change it so it matches only the number from 20 to 29?

    -
    - +
    +
    • 12
    • diff --git a/js/playfield.js b/js/playfield.js index 5a5be9b..d882144 100644 --- a/js/playfield.js +++ b/js/playfield.js @@ -22,7 +22,7 @@ function nomatchTextElement(string) { return span; } -function matchExample(match, example) { +function matchExample(match, isIncomplete, text, example) { var text = example.innerText; var start = match.index; var stop = match.index + match[0].length; @@ -34,7 +34,15 @@ function matchExample(match, example) { example.appendChild(nomatchTextElement(textBefore)); example.appendChild(matchTextElement(textMatch)); example.appendChild(nomatchTextElement(textAfter)); - example.classList.add("match"); + + if (!isIncomplete) { + example.classList.remove("incompletematch"); + example.classList.add("match"); + } else { + example.classList.remove("match"); + example.classList.add("incompletematch"); + } + example.classList.remove("nomatch"); } @@ -42,6 +50,7 @@ function unmatchExample(example) { var text = example.innerText; example.innerHTML = ""; example.appendChild(nomatchTextElement(text)); + example.classList.remove("incompletematch"); example.classList.remove("match"); example.classList.add("nomatch"); } @@ -57,10 +66,13 @@ function watchExpression(playfield, examples, regex, message) { return null; } } - function getReferenceRegex() { + function getReferenceInfo() { var reference = regex.getAttribute("reference"); try { - return RegExp(reference); + return { + "shouldMatchWholeLine": reference.startsWith('^') && reference.endsWith('$'), + "regex": RegExp(reference) + }; } catch (err) { message.innerHTML = translateReferenceWrongErrorMessage(err.message); return null; @@ -69,9 +81,9 @@ function watchExpression(playfield, examples, regex, message) { function check() { updateExperiment(); playfield.classList.remove("success"); - var reference = getReferenceRegex(); + var referenceInfo = getReferenceInfo(); var exp = getExpression(); - if (!exp || !reference) { + if (!exp || !referenceInfo) { return; } message.innerHTML = ""; @@ -83,7 +95,13 @@ function watchExpression(playfield, examples, regex, message) { var example = example_list[i]; var text = example.innerText; // determine if it should match - var shouldNotMatch = reference.exec(text) ? false : true; + var shouldNotMatch; + if (!referenceInfo.shouldMatchWholeLine) { + shouldNotMatch = referenceInfo.regex.exec(text) ? false : true; + } else { + var matches = text.match(referenceInfo.regex); + shouldNotMatch = matches?.length> 0 && matches[0] == text ? false : true; + } if (shouldNotMatch) { example.classList.add("fail"); example.classList.remove("ok"); @@ -94,7 +112,15 @@ function watchExpression(playfield, examples, regex, message) { // check the match var match = exp.exec(text); if (match) { - matchExample(match, example); + var matches = text.match(exp); + var isIncomplete = + referenceInfo.shouldMatchWholeLine + && matches?.length> 0 && matches[0] != text; + + matchExample(match, isIncomplete, text, example); + + // enforce overall result to fail if any match is incomplete + match = !isIncomplete; } else { unmatchExample(example); } @@ -130,7 +156,7 @@ function watchExpression(playfield, examples, regex, message) { var match = exp.exec(text); if (match) { experiment.classList.add("match"); - matchExample(match, content); + matchExample(match, false, text, content); } else { experiment.classList.add("nomatch"); unmatchExample(content);

    AltStyle によって変換されたページ (->オリジナル) /