Search Unity

Code Tags Alerter

Discussion in 'Meta-forum Discussion' started by Vryken, Aug 31, 2018.

  1. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    I (and probably many others) have noticed that there seem to be quite a few new users asking for help with their code, and they usually post it without making use of code tags. Just for fun, I've decided to try creating a way to alert a user when the thread or reply they are creating includes code, but not code tags, and was met with a nice result. I thought maybe something like this could be added as a feature to the forums here.

    Here's what I've put together using only raw JavaScript and regular expressions:
    Code (JavaScript):
    1. var messageBox;
    2.  
    3. var topLevelQuery = /public(\s*| abstract| static| partial)\s*(\s+| class| interface| struct| namespace)\s+.+(\s*|\s*:\s*\.+)\s*\{/g;
    4. var methodQuery = /.+\s*\(.*\)\s*(;|\{)/g;
    5. var conditionQuery = /((if|for|foreach|while|switch|catch)\s*\(.+?\)|(else|try|finally))\s*\{/g;
    6. var variableQuery = /.+ .+ = .+;/g;
    7.  
    8. var minTopLevelOccurrences = 1;
    9. var minMethodOccurrences = 1;
    10. var minConditionOccurrences = 1;
    11. var minVariableOccurrences = 1;
    12.  
    13. var hasAlerted = false;
    14.  
    15. newThreadOrReply();
    16.  
    17. function newThreadOrReply() {
    18.     try {
    19.         messageBox = document.getElementById("ThreadCreate").querySelector("iframe").contentWindow.document.querySelector("body");
    20.     }
    21.     catch {
    22.         messageBox = document.getElementById("QuickReply").querySelector("iframe").contentWindow.document.querySelector("body");
    23.     }
    24. }
    25.  
    26. messageBox.oninput = function () {
    27.     if (hasAlerted) { return; }
    28.  
    29.     if (occurrences(topLevelQuery) >= minTopLevelOccurrences &&
    30.         occurrences(methodQuery) >= minMethodOccurrences &&
    31.         occurrences(conditionQuery) >= minConditionOccurrences &&
    32.         occurrences(variableQuery) >= minVariableOccurrences) {
    33.  
    34.         if (!containsCodeTags()) {
    35.             alert("It looks like you are trying to post code. Please make sure to use code tags before posting.");
    36.             hasAlerted = true;
    37.         }
    38.     }
    39. }
    40.  
    41. function occurrences(query) {
    42.     try { return messageBox.innerText.match(query).length; }
    43.     catch { return 0; }
    44. }
    45.  
    46. function containsCodeTags() {
    47.     var openingTags = messageBox.innerText.search(/\[code=(CSharp|JavaScript|Boo)\]|\[ICODE\]/g);
    48.     var closingTags = messageBox.innerText.search(/\[\/code\]|\[\/ICODE\]/g);
    49.  
    50.     return (openingTags > -1) && (closingTags > -1);
    51. }
    What It Searches for:

    There are six different regular expressions being matched as the user types in the text area (messageBox):
    • topLevelQuery
    • methodQuery
    • conditionQuery
    • variableQuery
    • openingTags
    • closingTags
    topLevelQuery is an expression that searches for top-level declarations such as classes, interfaces, and namespaces, including different types (abstract, static, partial, etc) and inheritance/interface implementation.
    Some examples of matching expressions are:
    • public interface MyInterface {}
    • public static class MyClass {}
    • public abstract class MyClass : ParentClass {}
    methodQuery is an expression that searches for method declarations and calls, mainly using the existence of parentheses and semicolons as two of the major things to search for.
    Some examples of matching expressions are:
    • void MyMethod(int x, float y) {}
    • public virtual string MyMethod() {}
    • MyMethod();
    conditionQuery is an expression that searches for any type of condition such as if-statements, loops, and try-catch blocks.
    Some examples of matching expressions are:
    • if (whatever) {}
    • else {}
    • foreach(whatever){}
    variableQuery is the simplest expression, detecting if a line of text is a variable declaration by looking for two strings/characters, followed by an equal sign, followed by another string/character, followed by a semicolon.
    Some examples of matching expressions are:
    • int x = 10;
    • public char myChar = 'Q';
    • private static string myString = null;
    openingTags searches for what its name implies; any opening code tags such as "code=CSharp", "code=JavaScript", and "ICODE" (including the square brackets).

    closingTags again, searches for what its name implies; the closing tags "/code", and "/ICODE" (including the square brackets);

    How it Knows When to Alert:

    You'll notice that each of the four query expressions (topLevelQuery, methodQuery, conditionQuery, variableQuery) also have their own associated minimum number of occurrences (minTopLevelOccurrences, minMethodOccurrences, minConditionOccurrences, minVariableOccurrences).

    As the user is typing, it will check how many occurrences of each expression are present in the text area. The number of occurrences are all set to 1 by default, but can be changed if desired.
    If all minimum number of occurrences for each expression are met, it will then check if any code tags are present, and if not, then the user will be alerted that they appear to be wanting to post some code without using code tags.
    Obviously a simple alert() function shouldn't be the way to go about doing it for real; I imagine a box containing the message that highlights the code tags would appear instead, using some CSS to hide/show it.

    Testing:

    If you would like to test this code, you can open up your browser's inspector and copy/paste it into the console, then try inputting some code in the reply box below. You can also add this line at the top of the oninput function to see how many occurrences have been detected as you type:
    Code (JavaScript):
    1. console.log("tops: " + occurrences(topLevelQuery) + " | methods: " + occurrences(methodQuery) + " | conditions: " + occurrences(conditionQuery) + " | variables: " + occurrences(variableQuery));
    Closing:


    If the team in charge of the Unity forums (or anyone, really) would like to use and modify this code, feel free to do so; no strings attached. And don't worry, I won't be upset if this doesn't officially get added. I just had fun making it and wanted to share it.
     
    Last edited: Sep 9, 2018
    jc-drile77 likes this.
  2. jc-drile77

    jc-drile77

    Joined:
    Jul 1, 2014
    Posts:
    230
    Nice job! Would be a great addition indeed :)