1
yomichan-import/jmdictGlossary.go
2023-01-22 14:37:18 -06:00

301 lines
9.2 KiB
Go

package yomichan
import (
"fmt"
"strconv"
"foosoft.net/projects/jmdict"
)
func glossaryContainsLanguage(glossary []jmdict.JmdictGlossary, language string) bool {
hasGlosses := false
for _, gloss := range glossary {
if glossContainsLanguage(gloss, language) {
hasGlosses = true
break
}
}
return hasGlosses
}
func glossContainsLanguage(gloss jmdict.JmdictGlossary, language string) bool {
if gloss.Language == nil && language != "eng" {
return false
} else if gloss.Language != nil && language != *gloss.Language {
return false
} else {
return true
}
}
func makeGlossListItem(gloss jmdict.JmdictGlossary, language string) any {
contents := []any{gloss.Content}
listItem := contentListItem(contentAttr{}, contents...)
return listItem
}
func makeInfoGlossListItem(gloss jmdict.JmdictGlossary, language string) any {
// Prepend gloss with "type" (literal, figurative, trademark, etc.)
glossTypeCode := *gloss.Type
contents := []any{}
if name, ok := glossTypeCodeToName[LangCode{language, glossTypeCode}]; ok {
if name != "" {
italicStyle := contentAttr{fontStyle: "italic"}
contents = append(contents, contentSpan(italicStyle, "("+name+")"), " ")
}
} else {
fmt.Println("Unknown glossary type code " + *gloss.Type + " for build language " + language)
contents = append(contents, "["+glossTypeCode+"] ")
}
contents = append(contents, gloss.Content)
listItem := contentListItem(contentAttr{}, contents...)
return listItem
}
func makeSourceLangListItem(sourceLanguage jmdict.JmdictSource, language string) any {
contents := []any{}
var srcLangCode string
if sourceLanguage.Language == nil {
srcLangCode = "eng"
} else {
srcLangCode = *sourceLanguage.Language
}
// Format: [Language] ([Partial?], [Wasei?]): [Original word?]
// [Language]
if langName, ok := langCodeToName[LangCode{language, srcLangCode}]; ok {
contents = append(contents, langName)
} else {
contents = append(contents, srcLangCode)
fmt.Println("Unable to convert ISO 639 code " + srcLangCode + " to its full name in language " + language)
}
// ([Partial?], [Wasei?])
var sourceLangTypeCode string
if sourceLanguage.Type == nil {
sourceLangTypeCode = ""
} else {
sourceLangTypeCode = *sourceLanguage.Type
}
var sourceLangType string
if val, ok := sourceLangTypeCodeToType[LangCode{language, sourceLangTypeCode}]; ok {
sourceLangType = val
} else {
sourceLangType = sourceLangTypeCode
fmt.Println("Unknown source language type code " + sourceLangTypeCode + " for build language " + language)
}
if sourceLangType != "" && sourceLanguage.Wasei == "y" {
contents = append(contents, " ("+sourceLangType+", wasei)")
} else if sourceLangType != "" {
contents = append(contents, " ("+sourceLangType+")")
} else if sourceLanguage.Wasei == "y" {
contents = append(contents, " (wasei)")
}
// : [Original word?]
if sourceLanguage.Content != "" {
contents = append(contents, ": ")
attr := contentAttr{lang: ISOtoHTML[srcLangCode]}
contents = append(contents, contentSpan(attr, sourceLanguage.Content))
}
listItem := contentListItem(contentAttr{}, contents...)
return listItem
}
func makeReferenceListItem(reference string, refType string, meta jmdictMetadata) any {
contents := []any{}
attr := contentAttr{}
hint := refNoteHint[LangCode{meta.language, refType}]
contents = append(contents, hint+": ")
refHeadword, senseNumber, ok := parseReference(reference)
if !ok {
contents = append(contents, "【"+reference+"】")
return contentListItem(attr, contents...)
}
sequence, ok := meta.referenceToSeq[reference]
if !ok {
contents = append(contents, "【"+reference+"】")
return contentListItem(attr, contents...)
}
targetSense := senseID{
sequence: sequence,
number: senseNumber,
}
expHash := refHeadword.ExpHash()
doDisplayReading := (len(meta.expHashToReadings[expHash]) > 1)
doDisplaySenseNumber := (meta.seqToSenseCount[targetSense.sequence] > 1)
refGlossAttr := contentAttr{
fontSize: "65%",
verticalAlign: "middle",
data: map[string]string{"content": "refGlosses"},
}
contents = append(contents, refHeadword.ToInternalLink(doDisplayReading))
if doDisplaySenseNumber {
contents = append(contents, contentSpan(refGlossAttr, " "+strconv.Itoa(targetSense.number)+". "+meta.condensedGlosses[targetSense]))
} else {
contents = append(contents, contentSpan(refGlossAttr, " "+meta.condensedGlosses[targetSense]))
}
listItem := contentListItem(attr, contents...)
return listItem
}
func makeExampleListItem(sentence jmdict.JmdictExampleSentence) any {
if sentence.Lang == "jpn" {
return contentListItem(contentAttr{}, sentence.Text)
} else {
attr := contentAttr{
lang: ISOtoHTML[sentence.Lang],
listStyleType: ISOtoFlag[sentence.Lang],
}
return contentListItem(attr, sentence.Text)
}
}
func listAttr(lang string, listStyleType string, dataContent string) contentAttr {
return contentAttr{
lang: lang,
listStyleType: listStyleType,
data: map[string]string{"content": dataContent},
}
}
func needsStructuredContent(sense jmdict.JmdictSense, language string) bool {
for _, gloss := range sense.Glossary {
if glossContainsLanguage(gloss, language) && gloss.Type != nil {
return true
}
}
if len(sense.SourceLanguages) > 0 {
return true
} else if len(sense.Information) > 0 {
return true
} else if len(sense.Antonyms) > 0 {
return true
} else if len(sense.References) > 0 {
return true
} else if len(sense.Examples) > 0 {
return true
} else {
return false
}
}
func createGlossaryContent(sense jmdict.JmdictSense, meta jmdictMetadata) any {
glossaryContents := []any{}
// Add normal glosses
glossListItems := []any{}
for _, gloss := range sense.Glossary {
if glossContainsLanguage(gloss, meta.language) && gloss.Type == nil {
listItem := makeGlossListItem(gloss, meta.language)
glossListItems = append(glossListItems, listItem)
}
}
if len(glossListItems) > 0 {
attr := listAttr(ISOtoHTML[meta.language], "circle", "glossary")
list := contentUnorderedList(attr, glossListItems...)
glossaryContents = append(glossaryContents, list)
}
// Add information glosses
infoGlossListItems := []any{}
for _, gloss := range sense.Glossary {
if glossContainsLanguage(gloss, meta.language) && gloss.Type != nil {
listItem := makeInfoGlossListItem(gloss, meta.language)
infoGlossListItems = append(infoGlossListItems, listItem)
}
}
if len(infoGlossListItems) > 0 {
attr := listAttr(ISOtoHTML[meta.language], infoMarker, "infoGlossary")
list := contentUnorderedList(attr, infoGlossListItems...)
glossaryContents = append(glossaryContents, list)
}
// Add language-of-origin / loanword information
sourceLangListItems := []any{}
for _, sourceLanguage := range sense.SourceLanguages {
listItem := makeSourceLangListItem(sourceLanguage, meta.language)
sourceLangListItems = append(sourceLangListItems, listItem)
}
if len(sourceLangListItems) > 0 {
attr := listAttr(ISOtoHTML[meta.language], langMarker, "sourceLanguages")
list := contentUnorderedList(attr, sourceLangListItems...)
glossaryContents = append(glossaryContents, list)
}
// Add sense notes
noteListItems := []any{}
for _, information := range sense.Information {
listItem := contentListItem(contentAttr{}, information)
noteListItems = append(noteListItems, listItem)
}
if len(noteListItems) > 0 {
attr := listAttr(ISOtoHTML["jpn"], noteMarker, "notes") // notes often contain japanese text
list := contentUnorderedList(attr, noteListItems...)
glossaryContents = append(glossaryContents, list)
}
// Add antonyms
antonymListItems := []any{}
for _, antonym := range sense.Antonyms {
listItem := makeReferenceListItem(antonym, "ant", meta)
antonymListItems = append(antonymListItems, listItem)
}
if len(antonymListItems) > 0 {
attr := listAttr(ISOtoHTML[meta.language], antonymMarker, "antonyms")
list := contentUnorderedList(attr, antonymListItems...)
glossaryContents = append(glossaryContents, list)
}
// Add cross-references
referenceListItems := []any{}
for _, reference := range sense.References {
listItem := makeReferenceListItem(reference, "xref", meta)
referenceListItems = append(referenceListItems, listItem)
}
if len(referenceListItems) > 0 {
attr := listAttr(ISOtoHTML[meta.language], refMarker, "references")
list := contentUnorderedList(attr, referenceListItems...)
glossaryContents = append(glossaryContents, list)
}
// Add example sentences
exampleListItems := []any{}
for _, example := range sense.Examples {
for _, sentence := range example.Sentences {
listItem := makeExampleListItem(sentence)
exampleListItems = append(exampleListItems, listItem)
}
}
if len(exampleListItems) > 0 {
attr := listAttr(ISOtoHTML["jpn"], ISOtoFlag["jpn"], "examples")
list := contentUnorderedList(attr, exampleListItems...)
glossaryContents = append(glossaryContents, list)
}
return contentStructure(glossaryContents...)
}
func createGlossary(sense jmdict.JmdictSense, meta jmdictMetadata) []any {
glossary := []any{}
if needsStructuredContent(sense, meta.language) {
glossary = append(glossary, createGlossaryContent(sense, meta))
} else {
for _, gloss := range sense.Glossary {
if glossContainsLanguage(gloss, meta.language) {
glossary = append(glossary, gloss.Content)
}
}
}
return glossary
}