function is_uppercase(chr)
    local chr_code = string.byte(chr)
    local cond1 = chr_code >= string.byte("A") and chr_code <= string.byte("Z")
    return cond1
end

function is_lowercase(chr)
    local chr_code = string.byte(chr)
    local cond2 = chr_code >= string.byte("a") and chr_code <= string.byte("z")
    return cond2
end

function is_word_part(chr)
    return is_lowercase(chr) or is_uppercase(chr) or chr == "'"
end

function is_vowel(chr)
    local cond1 = chr == "a" or chr == "e" or chr == "i" or chr == "o" or chr == "u"
    local cond2 = chr == "A" or chr == "E" or chr == "I" or chr == "O" or chr == "U"
    return cond1 or cond2
end

function to_lowercase(word)
    local new_word = ""
    for i = 1, #word do
        local chr = string.sub(word, i, i)
        if is_uppercase(chr) then
            chr = string.char(string.byte(chr) + 32)
        end
        new_word = new_word .. chr
    end
    return new_word
end

function to_uppercase(word)
    local new_word = ""
    for i = 1, #word do
        local chr = string.sub(word, i, i)
        if is_lowercase(chr) then
            chr = string.char(string.byte(chr) - 32)
        end
        new_word = new_word .. chr
    end
    return new_word
end

function deapostrophize(word)
    local locs = {}
    local new_word = ""
    for i = 1, #word do
        local chr = string.sub(word, i, i)
        if chr == "'" then
            locs[#locs + 1] = i
        else
            new_word = new_word .. chr
        end
    end
    return {word = new_word, apostrophes = locs}
end

function random()
    if seed == nil then
        seed = 22515
    end
    seed = (1664525 * seed + 1013904223) % 4294967296
    return(seed / 4294967295)
 end

function get_mode()
    local prob = random()
    local mode = ""
    local done = false
    for i = 1, #modes do
        if not done then
            if prob <= mode_threshholds[modes[i]] then
                mode = modes[i]
                done = true
            end
        end
    end
    return mode
end

function not_common_word(word)
    local not_found = true
    for i = 1, #common_words do
        if to_lowercase(word) == common_words[i] then
            not_found = false
        end
    end
    return not_found
end

function de_an(index)
    if index ~= 1 then
        if words[index - 1] == "an" then
            words[index - 1] = "a"
        end
    end
end

function reapostrophize(word, apostrophes, probe, prefix)
    local new_word = ""
    if #apostrophes > 0 then
        local no_no_zone = {1, probe[1]}
        local displacement = #prefix - (probe[1] - 1)
        local apost_index = 1
        local word_index = 1
        local pre_word_aposts = 0
        if apostrophes[1] == 1 then
            new_word = "'"
            apost_index = apost_index + 1
            pre_word_aposts = pre_word_aposts + 1
            while apost_index <= #apostrophes and apostrophes[apost_index] == apost_index do
                new_word = new_word .. "'"
                apost_index = apost_index + 1
                pre_word_aposts = pre_word_aposts + 1
            end
        end
        while apost_index <= #apostrophes or word_index <= #word do
            if apost_index <= #apostrophes then
                local a_loc = apostrophes[apost_index]
                turbo_no_no_zone = {}
                turbo_no_no_zone[1] = no_no_zone[1] + pre_word_aposts
                turbo_no_no_zone[2] = no_no_zone[2] + apost_index - 1
                if a_loc > turbo_no_no_zone[1] and a_loc < turbo_no_no_zone[2] then
                    apost_index = apost_index + 1
                    displacement = displacement - 1
                elseif apostrophes[apost_index] + displacement == #new_word + 1 then
                    new_word = new_word .. "'"
                    apost_index = apost_index + 1
                else
                    new_word = new_word .. string.sub(word, word_index, word_index)
                    word_index = word_index + 1
                end
            else
                new_word = new_word .. string.sub(word, word_index, word_index)
                word_index = word_index + 1
            end
        end
    else
        new_word = word
    end
    return new_word
end

function modify_front(front, word)
    local new_front = ""
    local first_letter = string.sub(word, 1, 1)
    second_letter = string.sub(word, 2, 2)
    if is_uppercase(first_letter) then
        if #front > 1 then
            if is_uppercase(second_letter) then
                new_front = to_uppercase(front)
            else
                new_front = to_uppercase(string.sub(front, 1, 1))
                new_front = new_front .. string.sub(front, 2, #front)
            end
        else
            new_front = to_uppercase(front)
        end
    else
        new_front = front
    end
    return new_front
end

function lowercasefy(word)
    local new_word = ""
    local first_letter = string.sub(word, 1, 1)
    local second_letter = string.sub(word, 2, 2)
    if is_uppercase(first_letter) and is_lowercase(second_letter) then
        new_word = to_lowercase(first_letter) .. string.sub(word, 2, #word)
    else
        new_word = word
    end
    return new_word
end

function strip(word, probe)
    local found = false
    for i = 1, #word do
        local chr = string.sub(word, i, i)
        if not found and (is_vowel(chr) or (i > 1 and chr == "y")) then
            probe[1] = i
            found = true
        end
    end
    return string.sub(word, probe[1], #word)
end

function add_to_front(word, new_front, style, probe)
    local new_word = ""
    local first_letter = string.sub(word, 1, 1)
    local second_letter = string.sub(word, 2, 2)
    if is_vowel(first_letter) then
        new_word = modify_front(new_front, word) .. lowercasefy(word)
    elseif style == "first letter" then
        new_word = modify_front(new_front, word) .. string.sub(word, 2, #word)
        probe[1] = 2
    elseif style == "beginning consonants" then
        new_word = modify_front(new_front, word) .. strip(word, probe)
    end
    return new_word
end

function hashtag_at(word, percentage)
    local new_word = word
    if random() * 100 <= percentage then
        new_word = "#" .. word
    end
    return new_word
end

function perclify(index)
    local word = words[index]
    local info = deapostrophize(word)
    if not_common_word(word) and #info.word > 1 then
        local mode = get_mode()
        local new_word = ""
        local probe = {1}
        local prefix = ""
        if mode == "b" then
            de_an(index)
            prefix = "🅱️"
            new_word = add_to_front(info.word, prefix, "first letter", probe)
            new_word = hashtag_at(new_word, 5)
        elseif mode == "y" then
            de_an(index)
            prefix = "y"
            new_word = add_to_front(info.word, prefix, "first letter", probe)
            new_word = hashtag_at(new_word, 10)
        elseif mode == "z" then
            de_an(index)
            prefix = "z"
            new_word = add_to_front(info.word, prefix, "first letter", probe)
            new_word = hashtag_at(new_word, 10)
        elseif mode == "gl" then
            de_an(index)
            prefix = "gl"
            new_word = add_to_front(info.word, prefix, "beginning consonants", probe)
            new_word = hashtag_at(new_word, 25)
        elseif mode == "percl" then
            de_an(index)
            prefix = "percl"
            new_word = add_to_front(info.word, "percl", "beginning consonants", probe)
            new_word = hashtag_at(new_word, 40)
        elseif mode == "percl" then
            de_an(index)
            prefix = "j"
            new_word = add_to_front(info.word, "j", "first letter", probe)
            new_word = hashtag_at(new_word, 40)
        else
            new_word = info.word
        end
        local final_word = reapostrophize(new_word, info.apostrophes, probe, prefix)
        words[index] = final_word
    end
end

function extract_next_word(pos, text)
    local word_start, new_pos = 0, 0
    local finished = false
    local word_started = false
    local index = 0
    while not finished and pos + index <= #text do
        local chr = string.sub(text, pos + index, pos + index)
        if is_word_part(chr) and not word_started then
            word_start = pos + index
            word_started = true
        elseif not is_word_part(chr) and word_started then
            new_pos = pos + index
            finished = true
        end
        index = index + 1
    end
    if not word_started or not finished then
        word_start, new_pos = -1, -1
    end
    return {word_start = word_start, new_pos = new_pos}
end

function add_to_set(set, new_elem)
    local already_in = false
    for i = 1, #set do
        if set[i] == new_elem then
            already_in = true
        end
    end
    if not already_in then
        set[#set + 1] = new_elem
    end
end

function reset_rmp(reading_mrs_preset)
    reading_mrs_preset.new_line = false
    reading_mrs_preset.before_eq = true
    reading_mrs_preset.spaces = 0
    reading_mrs_preset.current_mode = ""
    reading_mrs_preset.reading_ratio_part = false
    reading_mrs_preset.most_recent_addition = ""
end

function print_array(a)
    local s = "{"
    for i = 1, #a do
        if type(a[i]) == "string" then
            s = s .. "\"" .. a[i] .. "\""
        else
            s = s .. tostring(a[i])
        end
        if i < #a then
            s = s .. ", "
        end
    end
    s = s .. "}"
    print(s)
end

function extract_mode(cfs)
    cfs = cfs .. "\n"
    local modes = {"_normal_"}
    local mode_ratio = {}
    local mode_ratio_setting = ""
    local mrps = {}
    local reading = false
    local word = ""
    local state = "parent scope"
    local reading_mrs_preset = {}
    local index = 1
    while index <= #cfs do
        chr = string.sub(cfs, index, index)
        if state == "parent scope" then
            if chr == ":" and word ~= "" then
                state = "reading mrs preset"
                reset_rmp(reading_mrs_preset)
                mrps[word] = {}
                reading_mrs_preset.most_recent_addition = word
            elseif word == "mode_ratio_setting" and chr == "=" then
                state = "reading mrs"
            end
        elseif state == "reading mrs preset" then
            if reading_mrs_preset.new_line then
                if chr == "\n" then
                    reading_mrs_preset.spaces = 0
                elseif reading_mrs_preset.spaces < 4 then
                    if chr ~= " " then
                        state = "parent scope"
                    elseif reading_mrs_preset.spaces == 3 and chr == " " then
                        reading_mrs_preset.new_line = false
                    end
                    reading_mrs_preset.spaces = reading_mrs_preset.spaces + 1
                end
            else
                if chr == "\n" then
                    reading_mrs_preset.new_line = true
                    reading_mrs_preset.spaces = 0
                end
                if reading_mrs_preset.before_eq and chr == "=" and word ~= "" then
                    add_to_set(modes, word)
                    reading_mrs_preset.current_mode = word
                    reading_mrs_preset.before_eq = false
                elseif not reading_mrs_preset.before_eq and word ~= "" then
                    reading_mrs_preset.reading_ratio_part = true
                end
            end
        end
        local cond = chr == " " or chr == "\n" or chr == "="
        cond = cond or (state ~= "reading mrs preset" and chr == ":")
        if cond then
            if reading then
                reading = false
                if reading_mrs_preset.reading_ratio_part then
                    reading_mrs_preset.reading_ratio_part = false
                    reading_mrs_preset.before_eq = true
                    if tonumber(word) then
                        local mrp = mrps[reading_mrs_preset.most_recent_addition]
                        mrp[reading_mrs_preset.current_mode] = tonumber(word)
                    end
                end
                if state == "reading mrs" then
                    mode_ratio_setting = word
                    state = "parent scope"
                end
            end
        else
            if not reading then
                reading = true
                word = ""
            end
            word = word .. chr
        end
        index = index + 1
    end
    local mrp = mrps[mode_ratio_setting]
    local sum = 0
    for i = 1, #modes do
        if mrp[modes[i]] == nil then
            mrp[modes[i]] = 0
        end
        sum = sum + mrp[modes[i]]
    end
    for i = 1, #modes do
        mode_ratio[modes[i]] = mrp[modes[i]] / sum
    end
    local mode_threshholds = {}
    local sum = 0
    for i = 1, #modes do
        sum = sum + mode_ratio[modes[i]]
        if sum == 0 then
            mode_threshholds[modes[i]] = -1
        elseif i == #modes then
            mode_threshholds[modes[i]] = 1
        else
            mode_threshholds[modes[i]] = sum
        end
    end
    return {modes = modes, mode_threshholds = mode_threshholds}
end

function parse(cws)
    local common_words = {}
    local cur_word = ""
    for i = 1, #cws do
        local chr = string.sub(cws, i, i)
        if chr == "\n" then
            common_words[#common_words + 1] = cur_word
            cur_word = ""
        else
            cur_word = cur_word .. chr
        end
    end
    common_words[#common_words + 1] = cur_word
    return common_words
end


f = assert(io.open("config.txt", "r"))
config_string = f:read("*all")
f:close()
modes_info = extract_mode(config_string)
modes = modes_info.modes
mode_threshholds = modes_info.mode_threshholds

f = assert(io.open("commonwords.txt", "r"))
common_words_string = f:read("*all")
f:close()
common_words = parse(common_words_string)

f = assert(io.open("copypasta.txt", "r"))
input_string = f:read("*all")
f:close()

done = false
pos = 1
words = {}
prec_words = {}
while not done do
    local info = extract_next_word(pos, input_string)
    if info.word_start == -1 then
        prec_words[#prec_words + 1] = string.sub(input_string, pos, #input_string)
        done = true
    else
        local prec_word = string.sub(input_string, pos, info.word_start - 1)
        local word = string.sub(input_string, info.word_start, info.new_pos - 1)
        prec_words[#prec_words + 1] = prec_word
        words[#words + 1] = word
        pos = info.new_pos
    end
end

for i = 1, #words do
    perclify(i)
end

output_string = ""
for i = 1, #words do
    output_string = output_string .. prec_words[i] .. words[i]
end
output_string = output_string .. prec_words[#prec_words]

print(output_string)

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: