heonian-conversation/generator.lua
2022-06-06 07:14:01 +02:00

575 lines
14 KiB
Lua

require "r2h2_modified"
require "quick-terminal-customization"
require "get_words"
words = getWords("heonian-content/words")
input = arg[1] or "input.txt"
function apply(text)
print(text)
end
function printD(...)
io.stderr:write(
string.effect(
TERMINAL_EFFECT.Bold,
string.color(
TERMINAL_COLOR.HighPurple,
"\tDEBUG:\t"
)
) ..
string.color(
TERMINAL_COLOR.HighPurple,
table.unpack({...}) , "\n"
)
)
end
function printW(...)
io.stderr:write(
string.effect(
TERMINAL_EFFECT.Bold,
string.color(
TERMINAL_COLOR.HighYellow,
"\t WARN:\t"
)
) ..
string.color(
TERMINAL_COLOR.HighYellow,
table.unpack({...}) .. "\n"
)
)
end
function printE(...)
io.stderr:write(
string.effect(
TERMINAL_EFFECT.Bold,
string.color(
TERMINAL_COLOR.HighRed,
"\tERROR:\t"
)
) ..
string.color(
TERMINAL_COLOR.HighRed,
table.unpack({...}) .. "\n"
)
)
end
function process_content(content)
content = content .. " "
for i=1, 2 do
if i == 1 then
apply_html("html/convo/text/start_roman.html")
else
apply_html("html/convo/text/start_heonian.html")
end
local ac = check_symbol(content)
while string.find(ac, " ") do
local new_word = string.sub(ac, 0, string.find(ac, " ")-1)
local indicators = {}
if i == 1 then
print_text = new_word
else
print_text = mod_convertToHeonian(new_word)
end
new_word = strip_symbols(new_word)
new_word, indicators = revert_verbs(new_word, indicators)
new_word, indicators = revert_nouns(new_word,indicators)
new_word, indicators = categorize_word(new_word,indicators)
add_word(new_word)
local REPLACE_WORD = strip_symbols(print_text)
local REPLACE_SEARCH = new_word
local REPLACE_PRINT = print_text
local REPLACE_DATA = ""
local k = 0
for _, v in pairs(indicators) do
if k > 0 then
REPLACE_DATA = REPLACE_DATA .. " "
end
REPLACE_DATA = REPLACE_DATA .. v
k = k + 1
end
local html_stuff = [[
<span
class="clickable"
onclick="showPopup('REPLACE_WORD','REPLACE_SEARCH','REPLACE_DATA')"
onmouseover="checkHover('REPLACE_WORD','REPLACE_SEARCH',this,'REPLACE_DATA')"
onmouseout="clearHover()">
REPLACE_PRINT
</span>
]]
while string.find(html_stuff, "REPLACE_PRINT") do
html_stuff = string.gsub(html_stuff, "REPLACE_PRINT", REPLACE_PRINT)
end
while string.find(REPLACE_WORD, "%\'") do
REPLACE_WORD = string.gsub(REPLACE_WORD, "%\'", "$")
end
while string.find(REPLACE_WORD, "%$") do
REPLACE_WORD = string.gsub(REPLACE_WORD, "%$", "\\\'")
end
while string.find(html_stuff, "REPLACE_WORD") do
html_stuff = string.gsub(html_stuff, "REPLACE_WORD", REPLACE_WORD)
end
while string.find(html_stuff, "REPLACE_SEARCH") do
html_stuff = string.gsub(html_stuff, "REPLACE_SEARCH", REPLACE_SEARCH)
end
if REPLACE_DATA and REPLACE_DATA ~= "" then
while string.find(REPLACE_DATA, "\t") do
REPLACE_DATA = string.gsub(REPLACE_DATA, "\t", " ")
end
while string.find(html_stuff, "REPLACE_DATA") do
html_stuff = string.gsub(html_stuff, "REPLACE_DATA", REPLACE_DATA)
end
else
html_stuff = string.gsub(html_stuff, ",'REPLACE_DATA'","")
end
apply(html_stuff)
ac = string.sub(ac, string.find(ac, " ")+1)
-- now we print the thing with teh appropiate indicators.
-- printD(print_text, table.unpack(indicators))
end
apply_html("html/convo/text/end.html")
end
end
function cell_builder(...)
arg = {...}
for i=1, #arg do
apply_html("html/words/definition/cell_start.html")
apply(arg[i])
apply_html("html/words/definition/cell_end.html")
end
end
function print_word_stuff(word)
apply_html("html/words/definition/start.html")
local exit = false
for _, v in pairs(words) do
if strip_symbols(v[1]) == strip_spaces(word) then
cell_builder(mod_convertToHeonian(word),v[1],v[3],v[2])
exit = true
end
end
if not exit then
-- personal pronuns
local PP = {
{"re","re","the speaker"," and someone else the listener doesn't know about"},
{"ba","ba","the listener"," and someone else the speaker doesn't know about"},
{"ima","ma","someone else","s who neither the speaker or the listener know about"}
}
for _, v1 in pairs(PP) do
for _, v2 in pairs(PP) do
if word == v1[1]..v2[2] then
exit = true
cell_builder(
mod_convertToHeonian(word),
word,
"Pronoun",
"This word refers to both "..v1[3] .. v2[4] .. ". \n\nIf in plural form, it refers to a group of people who all fit this definition."
)
end
end
end
if not exit then
cell_builder(mod_convertToHeonian(word),word, "???","???")
printW("\"" .. word .. "\" is not known")
end
end
apply_html("html/words/definition/end.html")
end
function add_word(str)
local add = true
for _, v in pairs(word_list) do
if v == str then
add = false
end
end
if add then
table.insert(word_list,str)
end
end
function strip_spaces(str)
while string.find(str, "% ") do
str = string.gsub(str, " ","")
end
return str
end
function strip_symbols(str)
local symbol_table = "'~()!?:></.,\t"
for i=1, #symbol_table do
while string.find(str, "%"..string.sub(symbol_table,i,i)) do
str = string.gsub(str, "%"..string.sub(symbol_table,i,i),"")
end
end
return str
end
function replace_sign(str)
while string.find(str, "%-") do
str = string.gsub(str, "%-"," ")
end
return str
end
function check_symbol(str)
if not in_dictionary(str) then
return replace_sign(str)
end
end
function find_n_replace(str, tbl,find,repl,indicator, caution)
if not in_dictionary(str) then
if string.find(str, find) then
if caution then
if not string.find(str, caution, string.find(str, find)+string.len(find)-string.len(caution)) then -- sometimes you want to avoid certain false positives
str = string.gsub(str,find, repl)
table.insert(tbl,indicator)
end
else
str = string.gsub(str,find, repl)
table.insert(tbl,indicator)
end
end
end
return str, tbl
end
function in_dictionary(str)
for i=1, #words do
if strip_symbols(words[i][1]) == str then return true end
end
end
function string.split(str, find, tbl)
split = tbl or {}
local p = 0
local continue = true
while continue do
word = string.sub(str,p,string.find(str,find,p+1,-1))
table.insert(split,strip_spaces(word))
if string.find(str,find,p) then
str = string.sub(str,p)
p = string.find(str,find,p)
continue = true
p = p + 1
else
continue = false
end
end
return split
end
function categorize_word(str,indicators)
local ind = {}
for _, v in pairs(words) do
if strip_symbols(v[1]) == strip_spaces(str) then -- if word is present
local ac = string.lower(v[3])
ind = string.split(strip_symbols(ac), " ", ind) -- store types are indicators
end
end
for _, v in pairs(indicators) do
table.insert(ind, v)
end
return str, ind
end
function check_morphemes(str, tbl,match,repl,indicators)
if type(indicators) ~= "table" then
indicators = {indicators}
end
if not in_dictionary(str) then
local flen = string.len(match)
if string.sub(str, -flen) == match then
str = string.sub(str, 0,string.len(str)-flen) .. repl
if tbl then
for _, v in pairs(indicators) do
table.insert(tbl,v)
end
end
end
end
return str, tbl
end
function revert_nouns(str, tbl)
-- possesion first
str, tbl = check_morphemes(str,tbl,"lan","","genitive")
str, tbl = check_morphemes(str,tbl,"la","","possesive")
-- then politeness
str, tbl = check_morphemes(str,tbl,"lfur","","formal-n1")
str, tbl = check_morphemes(str,tbl,"lafura","","formal-n2")
-- then plural
str, tbl = check_morphemes(str,tbl,"n","","plural")
-- personal pronuns
local PP = {
{"re","re"},
{"ba","ba"},
{"ima","ma"}
}
for _, v1 in pairs(PP) do
for _, v2 in pairs(PP) do
if str == v1[1]..v2[2] then
table.insert(tbl,"dual")
for _, vtbl in pairs(tbl) do
if vtbl == "plural" then
table.remove(tbl, #tbl)
break
end
end
table.insert(tbl,"pronoun")
end
end
end
return str, tbl
end
function revert_verbs(str, tbl)
-- moods first
str, tbl = revert_mood(str, tbl,"pash","","volitional-mood")
str, tbl = revert_mood(str, tbl,"dash","","imperative-mood")
str, tbl = revert_mood(str, tbl,"bash","","shy-mood")
str, tbl = revert_mood(str, tbl,"tash","","threat-mood")
str, tbl = revert_mood(str, tbl,"shu","","comfy-mood")
str, tbl = revert_mood(str, tbl,"ha","","excited-mood", "sha")
-- once we've cleaned moods lets try to get tense
str, tbl = check_morphemes(str, tbl,"kanya","ku",{"present-tense-formal","formal-v1"})
str, tbl = check_morphemes(str, tbl,"kome","ku",{"past-tense-formal","formal-v2"})
-- maybe it's informal?
str, tbl = check_morphemes(str, tbl,"nya","",{"present-tense-informal","informal-v1"})
str, tbl = check_morphemes(str, tbl,"me","",{"past-tense-informal","informal-v2"})
for _, v in pairs(tbl) do
if v == "informal-v1"
or v == "informal-v2" then
str = str .. "ku"
end
end
-- negate
str, tbl = check_morphemes(str, tbl,"faku","ku","negated")
return str, tbl
end
function revert_mood(str, tbl,match,repl,indicator, caution)
str, tbl = find_n_replace(str, tbl,"fa"..match,repl,indicator.."-negated",caution)
str, tbl = find_n_replace(str, tbl,match,repl,indicator,caution)
return str, tbl
end
function apply_html(path)
-- copy
local file = io.open(path,"r")
local html = file:read("*all")
file:close()
-- paste
apply(html)
end
function convo_image(string,alt_text)
if string then
apply_html("html/convo/header/image/start.html")
apply(string)
apply_html("html/convo/header/image/middle.html")
apply(alt_text)
apply_html("html/convo/header/image/end.html")
end
end
function convo_notes(string)
apply_html("html/convo/middle.html")
if string then
apply_html("html/convo/notes/start.html")
apply(string)
apply_html("html/convo/notes/end.html")
end
end
function convo_date(string)
if string then
apply_html("html/convo/header/date/start.html")
apply(string)
apply_html("html/convo/header/date/end.html")
end
end
function convo_header_start()
if not header then
header = true
apply_html("html/convo/header/start.html")
end
end
function convo_header_end()
if header then
header = false
apply_html("html/convo/header/end.html")
end
end
function convo_start(color)
convo_header_end()
if not convo then
if color then
apply_html("html/convo/start_green.html")
else
apply_html("html/convo/start_gray.html")
end
convo = true
end
end
function convo_end()
convo_header_end()
if convo then
if not notes then
apply_html("html/convo/middle.html")
end
notes = false
apply_html("html/convo/end.html")
convo = false
end
end
-- lets make the html
apply_html("html/start.html")
-- get text
local file = io.open(input,"r")
local text = file:read("*all")
file:close()
-- first analyze text
-- (this is the fun part)
word_list = {}
local p = 0
local s = 0
local convo = false
local header = false
local notes = false
local green = true
local skip = 1
local user = {}
while p ~= nil do
s = s + 1
local np = string.find(text,"\n",p+1)
if np and p - np ~= 1 then
if p then
skip = 1
if string.sub(text,p+1,p+1) == "\n"
or string.sub(text,p+1,p+1) == "/" then
-- end of new bubble
convo_end()
elseif string.sub(text,p+1,p+1) == "\t" then
-- its tabbed so its spoken?
convo_start()
process_content(string.sub(text,p+2,np-1))
elseif string.sub(text,p+1,p+1) == "h" then
-- spoken but forced to h
convo_start()
apply_html("html/convo/text/start_raw.html")
apply(mod_convertToHeonian(string.sub(text,p+3,np-1)).."")
apply_html("html/convo/text/end.html")
elseif string.sub(text,p+1,p+1) == "r" then
-- spoken but forced to r
convo_start()
apply_html("html/convo/text/start_raw.html")
apply(string.sub(text,p+3,np-1))
apply_html("html/convo/text/end.html")
elseif string.sub(text,p+1,p+1) == "i" then -- independant image, no username
convo_start(green)
convo_header_start()
convo_image(string.sub(text,p+3,np-1))
elseif string.sub(text,p+1,p+1) == "!" then -- independant image, no username
convo_notes(string.sub(text,p+3,np-1))
notes = true
else
-- new user name
convo_end()
if green then
green = false
else
green = true
end
convo_start(green)
-- this is a header section
convo_header_start()
-- lets check for images
local nl = string.find(text,"\n",p+1)
local nlp = string.find(text,"\n",nl+1)
current_user = string.sub(text,p+1,np-1)
user[current_user] = user[current_user] or {image = nil}
if nlp and string.sub(text,nl+1,nl+1) == "i" then
user[current_user].image = string.sub(text,nl+3,nlp-1)
skip = skip + 1
nl = string.find(text,"\n",nl+1)
nlp = string.find(text,"\n",nlp+1)
end
convo_image(user[current_user].image)
-- print name
apply_html("html/convo/header/name/start.html")
apply(string.sub(text,p+1,np-1))
apply_html("html/convo/header/name/end.html")
-- lets check for dates
if nlp and string.sub(text,nl+1,nl+1) == "d" then
convo_date(string.sub(text,nl+3,nlp-1))
skip = skip + 1
else
convo_date("")
end
header = true
end
end
while skip > 0 do
p = string.find(text,"\n",p+1)
skip = skip - 1
end
else
break
end
end
convo_end()
-- 3.5 separation
apply_html("html/spacer.html")
-- fourth lets make word lists
-- process contents
-- lets print the words
apply_html("html/spacer.html")
apply_html("html/words/start.html")
for i=1, #word_list do
print_word_stuff(word_list[i])
end
apply_html("html/words/end.html")
-- pop up
apply_html("html/pop_up.html")
-- lets end the html
apply_html("html/end.html")