package lang import "strings" // Shown är en bit text som spelaren ser, med hur den ska färgas. type Shown struct { Text string Known bool // ordet är känt (översatt/markerat) Reading bool // kana-ord som kan läsas men inte förstås Romaji string // läsning att visa under kända ord vid ShowsReadings } // Rendered är en skylt sedd genom spelarens kunskap. type Rendered struct { Original []Shown // originaltexten med kända ord markerade Partial []Shown // delvis översättning: kända ord översatta, resten kvar på japanska Complete bool // allt gick att läsa } // Render tolkar en japansk text med spelarens kunskap. k == nil betyder // "kan allt" (används när en skylt är avslöjad via hjälp). // // Japanska skrivs utan mellanslag, men när ett ord översätts till svenska // behöver det luft mot grannorden, annars blir det "新宿mot". Därför får // översatta ord ett mellanslag mot intilliggande text i den delvisa raden. func Render(d *Dictionary, k *Knowledge, s, uiLang string) Rendered { var out Rendered out.Complete = true prevTranslated := false // förra delen i Partial var ett översatt/läst ord addPartial := func(sh Shown, translated bool) { if n := len(out.Partial); n > 0 && (translated || prevTranslated) { prev := &out.Partial[n-1] if prev.Text != "" && !strings.HasSuffix(prev.Text, " ") && !strings.HasPrefix(sh.Text, " ") { prev.Text += " " } } out.Partial = append(out.Partial, sh) prevTranslated = translated } for _, seg := range d.Tokenize(s) { switch seg.Kind { case Word: known := k == nil || k.Knows(seg.Text) canRead := !known && k != nil && k.Kana && IsAllKana(seg.Text) orig := Shown{Text: seg.Text, Known: known, Reading: canRead} if known && k != nil && k.ShowsReadings() { orig.Romaji = seg.Entry.Romaji } out.Original = append(out.Original, orig) switch { case known: addPartial(Shown{Text: seg.Entry.Translation(uiLang), Known: true}, true) case canRead: addPartial(Shown{Text: seg.Entry.Romaji, Reading: true}, true) out.Complete = false default: addPartial(Shown{Text: seg.Text}, false) out.Complete = false } case Unknown: out.Original = append(out.Original, Shown{Text: seg.Text}) addPartial(Shown{Text: seg.Text}, false) out.Complete = false default: out.Original = append(out.Original, Shown{Text: seg.Text, Known: true}) addPartial(Shown{Text: seg.Text, Known: true}, false) } } return out } // PlainText slår ihop en rad till en sträng. func PlainText(line []Shown) string { s := "" for _, sh := range line { s += sh.Text } return s } // FirstUnknownWord returnerar det första ordboksordet i texten som spelaren // inte kan, eller "" om hen kan alla. func FirstUnknownWord(d *Dictionary, k *Knowledge, s string) string { for _, w := range d.WordsIn(s) { if !k.Knows(w) { return w } } return "" }