Golang : Mapping Iban to Dunging alphabets
For this tutorial, we will learn how to map Iban(Sea Dayak) language to the Dunging alphabets. According to this article by The Borneo Post, the Dunging alphabets was developed by Dunging ak Gunggu within a span of 15 years – from 1947 to 1962.
Handwritten notes in Dunging
NOTE : I'm not an Iban and I do not speak Iban language. For me, I just want the world to know about the existence of this written language of the Iban people.It would be nice to let the future generations know about this form of written language.
To get this Dunging mapping program to work, you will need the code below and the fonts. --> Click here to download the fonts(zip file). <--
Here you go!
package main
import (
"fmt"
"html/template"
"log"
"math"
"net/http"
"strings"
)
var dungingIbanMap = map[string]string{
"ah": "ah.jpg",
"ak": "ak.jpg",
"an": "an.jpg",
"am": "am.jpg",
"as": "as.jpg",
"ba": "ba.jpg",
"eig": "eig.jpg",
"e": "E.jpg", // case insensitive
"E": "E.jpg", // case insensitive
"iem": "iem.jpg",
"il": "il.jpg",
"is": "is.jpg",
"ka": "ka.jpg",
"na": "na.jpg",
"oh": "oh.jpg",
"ok": "ok.jpg",
"op": "op.jpg",
"pa": "pa.jpg",
"sa": "sa.jpg",
"un": "un.jpg",
"uw": "uw.jpg",
"a": "a.jpg", // case insensitive
"A": "A.jpg", // case insensitive
"al": "al.jpg",
"ao": "ao.jpg",
"at": "at.jpg",
"cha": "cha.jpg",
"ein": "ein.jpg",
"ek": "ek.jpg",
"ga": "ga.jpg",
"ieng": "ieng.jpg",
"ip": "ip.jpg",
"it": "it.jpg",
"la": "la.jpg",
"nga": "nga.jpg",
"oi": "oi.jpg",
"om": "om.jpg",
"or": "or.jpg",
"ra": "ra.jpg",
"ta": "ta.jpg",
"us": "us.jpg",
"ya": "ya.jpg",
"ang": "ang.jpg",
"ap": "ap.jpg",
"au": "au.jpg",
"da": "da.jpg",
"eix": "eix.jpg",
"eng": "eng.jpg",
"ieh": "ieh.jpg",
"I": "I.jpg", // case insensitive
"i": "I.jpg", // case insensitive
"ir": "ir.jpg",
"ja": "ja.jpg",
"ma": "ma.jpg",
"nya": "nya.jpg",
"O": "O.jpg", // case insensitive
"o": "O.jpg", // case insensitive
"ong": "ong.jpg",
"oug": "oug.jpg",
"R": "R.jpg", // case insensitive
"r": "R.jpg", // case insensitive
"ul": "ul.jpg",
"ut": "ut.jpg",
}
const inputPage = `<html><body>
<form method="post" action="/dunging">
<p><h1>Get Dunging alphabets</h2></p>
<p>
<textarea name="input" rows="4" cols="50"></textarea><br>
</p>
<p>
<input type="submit" name="Get Dunging Alpabets" value="Get Dunging Alpabets">
</p>
</form>
<p><img src="https://www.omniglot.com/images/writing/iban2.gif"></p>
</body></html>`
var inputTemplate = template.Must(template.New("").Parse(inputPage))
func dungingInputPageHandler(w http.ResponseWriter, r *http.Request) {
conditionsMap := map[string]interface{}{}
if err := inputTemplate.Execute(w, conditionsMap); err != nil {
log.Println(err)
}
}
func dungingIban(w http.ResponseWriter, r *http.Request) {
if r.FormValue("input") != "" {
input := r.FormValue("input")
header := `<!DOCTYPE html>
<html>
<head>
<script>
function goBack() {
window.history.back()
}
</script>
</head>
<body>
<button onclick="goBack()">Go Back</button><br><br>`
w.Write([]byte(fmt.Sprintf("%s", header)))
for k, v := range strings.Fields(strings.ToLower(input)) {
fmt.Println(k, v, dungingIbanMap[string(v)])
img := "<img src='/fonts/" + dungingIbanMap[string(v)] + "'>"
w.Write([]byte(fmt.Sprintf("%s", img)))
}
footer := `</body></html>`
w.Write([]byte(fmt.Sprintf("%s", footer)))
}
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", dungingInputPageHandler)
mux.HandleFunc("/dunging", dungingIban)
fileServer := http.FileServer(http.Dir("./fonts"))
mux.Handle("/fonts/", http.StripPrefix("/fonts", fileServer))
port := ":9999"
fmt.Println("Point your browser to localhost" + port)
http.ListenAndServe(port, mux)
//-------------------------------------------------------------------------------------
// the program should executing here. Below are some of my research codes that you might be interested to explore later.
//-------------------------------------------------------------------------------------
// sanity check test
//all := "is cha op sa or ya ma nya om au us ka it oi A ja ga ok E pa am as ieh iem ao oh ah ut al ak nga ieng an un ek ip a uw il I ra ap ta na da at ul eng la ein ba ong eix eig ir ang oug R O"
//allSlice := strings.Fields(all)
//for k, v := range allSlice {
// fmt.Println(k, string(v), dungingIbanMap[string(v)])
//}
//ibanText := "Selamat Datai" <-- this is present day Iban(similar to BM) -- cannot use!
//ibanText := "salamat datai" // <-- old way of writing?
//ibanText := "chabut" // remember! the Dunging fonts were created back in 1962!!
// nevermind, we use the first line of PANTUN IBAN LENYAU SURAT
ibanText := []string{"da a ya ao", "la a ma ao", "ma ra ein ao", "ka a op it ya ao", "la a ma ao", "ja ma an"}
for i, j := range ibanText {
fmt.Println("Line : ", i)
for k, v := range strings.Fields(strings.ToLower(j)) {
fmt.Println(k, v, dungingIbanMap[string(v)])
}
}
// first, scan for 2 characters because this group is the most common
//processedIbanText := chunkSplit(ibanText, 2, " ")
//lower case every characters
//for _, v := range strings.Fields(strings.ToLower(processedIbanText)) {
//fmt.Println(string(v), dungingIbanMap[string(v)])
// if dungingIbanMap[string(v)] != "" {
// twoCharsMapped = append(twoCharsMapped, dungingIbanMap[string(v)])
// } else {
// twoCharsMapped = append(twoCharsMapped, string(v))
// }
//}
}
// from https://stackoverflow.com/questions/27516387/what-is-the-correct-way-to-find-the-min-between-two-integers-in-go
func MinOf(vars ...float64) float64 {
min := vars[0]
for _, i := range vars {
if min > i {
min = i
}
}
return min
}
func translatedChangeDistance(old, new int) (delta float64) {
diff := float64(new - old)
delta = (diff / float64(old)) * 100
return math.Abs(delta) // turn negative to positive
}
func countMappings(inputMap []string) float64 {
// how many items in the slice?
length := len(inputMap)
counter := 0
for _, v := range inputMap {
counter = counter + strings.Count(string(v), ".jpg")
//fmt.Println(string(v))
}
//fmt.Println("Length ", length)
//fmt.Println("Counter ", counter)
totalTranslated := translatedChangeDistance(length, counter)
return totalTranslated
}
// from https://www.socketloop.com/tutorials/golang-chunk-split-or-divide-a-string-into-smaller-chunk-example
func chunkSplit(body string, limit int, end string) string {
var charSlice []rune
// push characters to slice
for _, char := range body {
charSlice = append(charSlice, char)
}
var result string = ""
for len(charSlice) >= 1 {
// convert slice/array back to string
// but insert end at specified limit
result = result + string(charSlice[:limit]) + end
// discard the elements that were copied over to result
charSlice = charSlice[limit:]
// change the limit
// to cater for the last few words in
// charSlice
if len(charSlice) < limit {
limit = len(charSlice)
}
}
return result
}
Sample output:
Happy coding!
References:
https://www.theborneopost.com/2012/06/20/long-lost-iban-alphabet-script-found/
https://www.theborneopost.com/newsimages/2012/06/00000051366.jpg
https://www.facebook.com/BorneoUnion/posts/277523265716428
https://www.theborneopost.com/2012/09/19/dunging-alphabet-made-easier/
https://dayakwithgoldenhair.wordpress.com/2011/10/03/dungings-legacy-the-iban-alphabet/
https://en.wikipedia.org/wiki/Iban_language
https://m.facebook.com/planetsarawak/photos/a.800432576665602/800428833332643/?type=3
See also : Golang : Gargish-English language translator
By Adam Ng(黃武俊)
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+5.2k Golang : Reclaim memory occupied by make() example
+6.9k Golang : Array mapping with Interface
+9.4k Golang : Quadratic example
+28.2k Golang : Read, Write(Create) and Delete Cookie example
+8.9k Golang : Intercept and compare HTTP response code example
+23.7k Golang : Call function from another package
+9.7k Golang : Function wrapper that takes arguments and return result example
+7.8k Golang : What fmt.Println() can do and println() cannot do
+8.6k Golang : Accept any number of function arguments with three dots(...)
+25.6k Golang : Convert IP address string to long ( unsigned 32-bit integer )
+16k Golang : convert string or integer to big.Int type
+5.4k Golang : Detect words using using consecutive letters in a given string