Jump to content

MediaWiki:Common.js: Difference between revisions

From Knowledge Base
No edit summary
No edit summary
Line 104: Line 104:
});
});


// Highlight C# comments (single-line and multi-line)
document.querySelectorAll("pre.csharp").forEach(pre => {
document.querySelectorAll("pre.csharp").forEach(pre => {
     let code = pre.innerHTML;
     let code = pre.innerHTML;


     // First, handle comments separately so keywords inside comments are not affected
     // First, handle comments separately so keywords inside comments are not affected
    // Regex for matching single-line comments (//)
     const regexSingleLineComments = /(\/\/.*)/g;
     const regexSingleLineComments = /(\/\/.*)/g;
     code = code.replace(regexSingleLineComments, match => {
     code = code.replace(regexSingleLineComments, match => {
Line 115: Line 113:
     });
     });


    // Regex for matching multi-line comments (/* */)
     const regexMultiLineComments = /(\/\*[\s\S]*?\*\/)/g;
     const regexMultiLineComments = /(\/\*[\s\S]*?\*\/)/g;
     code = code.replace(regexMultiLineComments, match => {
     code = code.replace(regexMultiLineComments, match => {
Line 121: Line 118:
     });
     });


     // Now, highlight the rest of the code, excluding comments
     // Temporarily remove the comments to process the rest of the code
    // Remove highlighted comments from the code temporarily for processing
     const codeWithoutComments = code.replace(/<span class="csharp-comment">[\s\S]*?<\/span>/g, match => {
     const codeWithoutComments = code.replace(/<span class="csharp-comment">[\s\S]*?<\/span>/g, (match) => {
         return match.replace(/<span class="csharp-comment">|<\/span>/g, ''); // Extract raw code from comment spans
         return match.replace(/<span class="csharp-comment">|<\/span>/g, '');
     });
     });


     // Define the regex pattern for class names (PascalCase)
     // Regex patterns for various C# elements
     const regexClasses = /\b([A-Z][a-zA-Z0-9_]*)\b/g;
     const regexClasses = /\b([A-Z][a-zA-Z0-9_]*)\b/g;
    const regexProperties = /\b([a-zA-Z_][a-zA-Z0-9_]*)\s*(?=\s*{)/g;
    const regexKeywords = new RegExp(`\\b(${csharpKeywords.join("|")})\\b`, "g");
    const regexTypes = new RegExp(`\\b(${csharpTypes.join("|")})\\b`, "g");
    const regexMethods = /\b([a-zA-Z_][a-zA-Z0-9_]*)\s*(?=\()/g;


     // Define the regex pattern for property names (PascalCase, followed by getter/setter)
     // Highlighting C# code
     const regexProperties = /\b([a-zA-Z_][a-zA-Z0-9_]*)\s*(?=\s*{)/g;
     let updatedCode = codeWithoutComments;


     // Highlight C# keywords
     updatedCode = updatedCode.replace(regexKeywords, (match, p1) => {
    const regexKeywords = new RegExp(`\\b(${csharpKeywords.join("|")})\\b`, "g");
        return `<span class="csharp-keyword">${p1}</span>`;
    let updatedCode = codeWithoutComments.replace(regexKeywords, '<span class="csharp-keyword">$1</span>');
    });


    // Highlight C# types
     updatedCode = updatedCode.replace(regexTypes, (match, p1) => {
    const regexTypes = new RegExp(`\\b(${csharpTypes.join("|")})\\b`, "g");
        return `<span class="csharp-type">${p1}</span>`;
     updatedCode = updatedCode.replace(regexTypes, '<span class="csharp-type">$1</span>');
    });


    // Highlight C# method names
     updatedCode = updatedCode.replace(regexMethods, (match, p1) => {
    const regexMethods = /\b([a-zA-Z_][a-zA-Z0-9_]*)\s*(?=\()/g;
        return `<span class="csharp-method">${p1}</span>`;
     updatedCode = updatedCode.replace(regexMethods, '<span class="csharp-method">$1</span>');
    });


    // Highlight C# class names and property names
     updatedCode = updatedCode.replace(regexClasses, (match, p1) => {
     updatedCode = updatedCode.replace(regexClasses, (match, p1) => {
         return isKeyword(p1) ? p1 : `<span class="csharp-class">${p1}</span>`;
         return isKeyword(p1) ? p1 : `<span class="csharp-class">${p1}</span>`;
     });
     });
     updatedCode = updatedCode.replace(regexProperties, (match, p1) => {
     updatedCode = updatedCode.replace(regexProperties, (match, p1) => {
         return isKeyword(p1) ? p1 : `<span class="csharp-property">${p1}</span>`;
         return isKeyword(p1) ? p1 : `<span class="csharp-property">${p1}</span>`;
     });
     });


     // Reinsert the highlighted comments into the updated code
     // Reinsert comments back into the code
     code = updatedCode.replace(/<span class="csharp-comment">[\s\S]*?<\/span>/g, (match) => {
     code = updatedCode.replace(/<span class="csharp-comment">[\s\S]*?<\/span>/g, (match) => {
         return match; // No changes needed to the comment highlight
         return match; // Keep the comment spans intact
     });
     });


    // Update the inner HTML of the <pre> element with the highlighted code
     pre.innerHTML = code;
     pre.innerHTML = code;
});
});

Revision as of 21:56, 18 January 2025

// Add 'csharp' class to all <pre> tags for easier targeting
document.querySelectorAll("pre").forEach(pre => pre.classList.add("csharp"));

// Define C# keywords
const csharpKeywords = [
    "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked",
    "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", 
    "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", 
    "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", 
    "new", "null", "object", "operator", "out", "override", "params", "private", "protected", 
    "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", 
    "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", 
    "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while"
];

// Highlight C# keywords
document.querySelectorAll("pre.csharp").forEach(pre => {
    let code = pre.innerHTML;
    const regex = new RegExp(`\\b(${csharpKeywords.join("|")})\\b`, "g");
    code = code.replace(regex, '<span class="csharp-keyword">$1</span>');
    pre.innerHTML = code;
});

// Define C# types
const csharpTypes = [
    "int", "long", "float", "double", "decimal", "char", "string", "bool", "byte", "object", 
    "void", "var", "dynamic", "sbyte", "ushort", "uint", "ulong"
];

// Highlight C# types
document.querySelectorAll("pre.csharp").forEach(pre => {
    let code = pre.innerHTML;
    const regexTypes = new RegExp(`\\b(${csharpTypes.join("|")})\\b`, "g");
    code = code.replace(regexTypes, '<span class="csharp-type">$1</span>');
    pre.innerHTML = code;
});

// Highlight C# method names
document.querySelectorAll("pre.csharp").forEach(pre => {
    let code = pre.innerHTML;

    // Define the regex pattern for method names (excluding C# keywords and types)
    const regexMethods = /\b([a-zA-Z_][a-zA-Z0-9_]*)\s*(?=\()/g;
    
    // Apply the method name highlighting
    code = code.replace(regexMethods, '<span class="csharp-method">$1</span>');
    
    pre.innerHTML = code;
});

// Function to check if a word is a keyword
function isKeyword(word) {
    return csharpKeywords.includes(word);
}

// Highlight C# class names and property names
document.querySelectorAll("pre.csharp").forEach(pre => {
    let code = pre.innerHTML;

    // Define the regex pattern for class names (PascalCase)
    const regexClasses = /\b([A-Z][a-zA-Z0-9_]*)\b/g;
    code = code.replace(regexClasses, (match, p1) => {
        return isKeyword(p1) ? p1 : `<span class="csharp-class">${p1}</span>`;
    });

    // Define the regex pattern for property names (PascalCase, followed by getter/setter)
    const regexProperties = /\b([a-zA-Z_][a-zA-Z0-9_]*)\s*(?=\s*{)/g;
    code = code.replace(regexProperties, (match, p1) => {
        return isKeyword(p1) ? p1 : `<span class="csharp-property">${p1}</span>`;
    });

    pre.innerHTML = code;
});

// Add rainbow curly braces highlighting with matched colors for each pair
const rainbowColors = [
    "red", "green", "blue", "purple", "orange", "yellow", "pink", "cyan", "lime", "brown"
];

document.querySelectorAll("pre.csharp").forEach(pre => {
    let code = pre.innerHTML;
    let braceStack = [];
    let braceCount = 0;

    // Regex for matching curly braces and adding colors
    code = code.replace(/{|}/g, (brace, offset) => {
        const color = rainbowColors[braceCount % rainbowColors.length];

        // Check if this is an opening brace
        if (brace === "{") {
            braceStack.push(color);  // Push color for opening brace
        } else {
            const pairColor = braceStack.pop();  // Pop the last opened brace's color for closing brace
            braceCount++;
            return `<span class="csharp-brace" style="color: ${pairColor};">${brace}</span>`;
        }

        // Apply color to opening brace
        braceCount++;
        return `<span class="csharp-brace" style="color: ${color};">${brace}</span>`;
    });

    pre.innerHTML = code;
});

document.querySelectorAll("pre.csharp").forEach(pre => {
    let code = pre.innerHTML;

    // First, handle comments separately so keywords inside comments are not affected
    const regexSingleLineComments = /(\/\/.*)/g;
    code = code.replace(regexSingleLineComments, match => {
        return `<span class="csharp-comment">${match}</span>`;
    });

    const regexMultiLineComments = /(\/\*[\s\S]*?\*\/)/g;
    code = code.replace(regexMultiLineComments, match => {
        return `<span class="csharp-comment">${match}</span>`;
    });

    // Temporarily remove the comments to process the rest of the code
    const codeWithoutComments = code.replace(/<span class="csharp-comment">[\s\S]*?<\/span>/g, match => {
        return match.replace(/<span class="csharp-comment">|<\/span>/g, ''); // Extract raw code from comment spans
    });

    // Regex patterns for various C# elements
    const regexClasses = /\b([A-Z][a-zA-Z0-9_]*)\b/g;
    const regexProperties = /\b([a-zA-Z_][a-zA-Z0-9_]*)\s*(?=\s*{)/g;
    const regexKeywords = new RegExp(`\\b(${csharpKeywords.join("|")})\\b`, "g");
    const regexTypes = new RegExp(`\\b(${csharpTypes.join("|")})\\b`, "g");
    const regexMethods = /\b([a-zA-Z_][a-zA-Z0-9_]*)\s*(?=\()/g;

    // Highlighting C# code
    let updatedCode = codeWithoutComments;

    updatedCode = updatedCode.replace(regexKeywords, (match, p1) => {
        return `<span class="csharp-keyword">${p1}</span>`;
    });

    updatedCode = updatedCode.replace(regexTypes, (match, p1) => {
        return `<span class="csharp-type">${p1}</span>`;
    });

    updatedCode = updatedCode.replace(regexMethods, (match, p1) => {
        return `<span class="csharp-method">${p1}</span>`;
    });

    updatedCode = updatedCode.replace(regexClasses, (match, p1) => {
        return isKeyword(p1) ? p1 : `<span class="csharp-class">${p1}</span>`;
    });

    updatedCode = updatedCode.replace(regexProperties, (match, p1) => {
        return isKeyword(p1) ? p1 : `<span class="csharp-property">${p1}</span>`;
    });

    // Reinsert comments back into the code
    code = updatedCode.replace(/<span class="csharp-comment">[\s\S]*?<\/span>/g, (match) => {
        return match; // Keep the comment spans intact
    });

    // Update the inner HTML of the <pre> element with the highlighted code
    pre.innerHTML = code;
});