t4rd

Make any text l33t.

Download

Source code

t4rd.c

/**
* 't4rd' by Inky <http://boxofjunk.ws/>
*   - v1.02 [14 May 2007]  Rewritten; significantly less ugly
*   - v0.01 [30 Apr 2007]  The original
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define PROG_VERSION "1.02"
#define PROG_DATE "14 May 2007"
#define LETTERS 26
#define L_CASE 0
#define U_CASE 1
#define CTRL_D 4

/* Letter mutations */
#define MAX_MUTS 6
const char *muts[LETTERS][MAX_MUTS+1] = {
    { "4", "@" },   // a
    { "|3", "8" },  // b
    { "(", "<" },    // c
    { "|)" }, // d
    { "3" },  // e
    { "/=", "|=" }, // f
    { "9", "6" },   // g
    { "|-|", "/-/", "]-[" },  // h
    { "1", "|", "!" },  // i
    { "_|", "_/" }, // j
    { "|<" },  // k
    { "1", "|_" },  // l
    { "/\\/\\", "|\\/|", "|V|", "/V\\", "]V[", "/|\\" },  // m
    { "/\\/", "/V", "|\\|", "]\\[" },  // n
    { "0", "()" },  // o
    { "|>", "|\"", "|*" },  // p
    {},     // q
    { "|2" }, // r
    { "5", "$" },   // s
    { "+", "7" },   // t
    { "|_|" },    // u
    { "\\/" },    // v
    { "\\/\\/", "vv", "\\^/", "\\|/" },  // w
    { "><", "}{", ")(" },  // x
    { "`/" }, // y
    {}      // z
};
unsigned short muts_len[26];

/* Convert a character to lowercase */
inline char chcase(const char chr, short charcase)
{
    switch (charcase) {
    case L_CASE:
        return ((chr >= 'A' && chr <= 'Z') ? chr+0x20 : chr);
    case U_CASE:
        return ((chr >= 'a' && chr <= 'z') ? chr-0x20 : chr);
    default:
        return chr;
    }
}

/* Print a letter in random case */
void putletter(const char chr)
{
    unsigned short r = rand() % 3;
    switch (r) {
    case 1:   // print in upper case
        putchar(chcase(chr, U_CASE));
        break;
    case 2:   // print in lower case
        putchar(chcase(chr, L_CASE));
        break;
    default:  // no change
        putchar(chr);
    }
}

/* t4rdify a string */
void t4rd(const char *str)
{
    char c;
    unsigned int i, m;
    for (i = 0; str[i] != '\0'; i++) {
        c = chcase(str[i], L_CASE);
        if (c < 'a' || c > 'z') {
            putchar(c);
        } else {
            m = muts_len[c-'a'];
            if (m > 0) {
                // 1 in 5 chance of printing
                // a (relatively) normal letter
                if (rand() % 5 == 1)
                    putletter(str[i]);
                else
                    printf("%s", muts[c-'a'][rand() % m]);
            } else {
                putletter(c);
            }
        }
    }
}

/* Run ze program! */
int main(int argc, char *argv[])
{
    unsigned int i, j, len = 0, maxlen = 1024;
    char in, *data;
    
    // initialise stuff
    srand(time(NULL));
    for (i = 0; i < LETTERS; i++) {
        for (j = 0; muts[i][j] != NULL; muts_len[i]++, j++);
    }
    
    if (argc > 1) {
        // print help message
        if (strcmp(argv[1], "--help") == 0 ||
            strcmp(argv[1], "-h") == 0) {
            printf("T4RD - version " PROG_VERSION
                    " by Inky, " PROG_DATE "\n\n");
            printf("Usage: %s [TEXT]\n", argv[0]);
            printf("   or: %s < [FILENAME]\n", argv[0]);
            printf("\nReport bugs to <inky@boxo"
                    "fjunk.ws>\n");
            exit(0);
        }
        
        // t4rdify the arguments
        for (i = 1; i < argc; i++) {
            t4rd(argv[i]);
            putchar((i < argc-1) ? ' ' : '\n');
        }
    } else {
        // read data from stdin and t4rdify it
        data = (char*)malloc(sizeof(char) * maxlen);
        while ((in = getchar()) != EOF && in != CTRL_D) {
            // backspace
            if (in == 8) {
                if (len > 0) data[--len] = '\0';
                continue;
            }
            
            // allocate memory for the string
            if (len >= maxlen) {
                maxlen <<= 1;
                data = (char*)realloc(data,
                        sizeof(char) * maxlen);
            }
            
            data[len++] = in;
        }
        t4rd(data);
        
        // print a trailing line break if needed
        if (data[len-1] != '\n') putchar('\n');
    }
    return 0;
}