Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - Improving Structures for Examples and Pronunciations #26

Merged
merged 2 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 4 additions & 18 deletions internal/io/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func printDictionaryEntry(writer *defineio.PanicWriter, entry source.DictionaryE

writer.IndentWritesBy(uint(len(prefix)), func(writer *defineio.PanicWriter) {
for _, examples := range sense.Examples {
writer.WriteStringLine(fmt.Sprintf("%q", examples))
writer.WriteStringLine(examples.String())
}

for _, notes := range sense.Notes {
Expand All @@ -110,7 +110,7 @@ func printDictionaryEntry(writer *defineio.PanicWriter, entry source.DictionaryE

writer.IndentWritesBy(uint(len(prefix)), func(writer *defineio.PanicWriter) {
if len(subSense.Examples) > 0 {
writer.WriteStringLine(fmt.Sprintf("%q", subSense.Examples[0]))
writer.WriteStringLine(subSense.Examples[0].String())
}
})
}
Expand Down Expand Up @@ -156,7 +156,7 @@ func getHeader(result source.DictionaryResult) string {
header := firstEntry.Word

if len(firstEntry.Pronunciations) > 0 {
header = fmt.Sprintf("%s %s", header, getPronunciationsText(firstEntry.Pronunciations))
header = fmt.Sprintf("%s %s", header, firstEntry.Pronunciations)
}

return header
Expand All @@ -166,7 +166,7 @@ func getEntryHeader(resultHeader string, lastEntryHeader string, lastWord string
var header string

if len(entry.Pronunciations) > 0 {
header = fmt.Sprintf("%s %s", entry.Word, getPronunciationsText(entry.Pronunciations))
header = fmt.Sprintf("%s %s", entry.Word, entry.Pronunciations)
} else if entry.Word != lastWord {
header = entry.Word
}
Expand All @@ -177,17 +177,3 @@ func getEntryHeader(resultHeader string, lastEntryHeader string, lastWord string

return header
}

func getPronunciationsText(pronunciations []string) string {
var pronunciationText string

if len(pronunciations) > 0 {
pronunciationText = fmt.Sprintf("/%s/", pronunciations[0])
}

if len(pronunciations) > 1 {
pronunciationText = fmt.Sprintf("%s (/%s/)", pronunciationText, strings.Join(pronunciations[1:], "/ /"))
}

return pronunciationText
}
12 changes: 6 additions & 6 deletions source/freedictionaryapi/apidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ func (r apiResponse) toResults() []source.DictionaryResult {
for _, result := range r {
sourceEntries := make([]source.DictionaryEntry, 0, len(result.Meanings))

var pronunciations []string
var pronunciations []source.Pronunciation
if result.Phonetic != "" {
pronunciation := cleanPhoneticText(result.Phonetic)

pronunciations = append(pronunciations, pronunciation)
pronunciations = append(pronunciations, source.Pronunciation(pronunciation))
}

for _, phonetic := range result.Phonetics {
Expand All @@ -86,8 +86,8 @@ func (r apiResponse) toResults() []source.DictionaryResult {

pronunciation := cleanPhoneticText(phonetic.Text)

if len(pronunciations) < 1 || pronunciations[0] != pronunciation {
pronunciations = append(pronunciations, pronunciation)
if len(pronunciations) < 1 || string(pronunciations[0]) != pronunciation {
pronunciations = append(pronunciations, source.Pronunciation(pronunciation))
}
}

Expand Down Expand Up @@ -140,14 +140,14 @@ func (v *apiThesaurusValues) toThesaurusValues() source.ThesaurusValues {
// toSense converts the API definition to a source.Sense
func (d *apiDefinition) toSense() source.Sense {
var definitions []string
var examples []string
var examples []source.AttributedText

if d.Definition != "" {
definitions = []string{d.Definition}
}

if d.Example != "" {
examples = []string{d.Example}
examples = []source.AttributedText{{Text: d.Example}}
}

return source.Sense{
Expand Down
74 changes: 40 additions & 34 deletions source/oxford/apidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,38 +107,41 @@ type apiSense struct {
Registers []apiIDText `json:"registers"`
Text string `json:"text"`
} `json:"constructions"`
CrossReferenceMarkers []string `json:"crossReferenceMarkers"`
CrossReferences []apiTypedIDText `json:"crossReferences"`
Definitions []string `json:"definitions"`
DomainClasses []apiIDText `json:"domainClasses"`
Domains []apiIDText `json:"domains"`
Etymologies []string `json:"etymologies"`
Examples []struct {
Definitions []string `json:"definitions"`
Domains []apiIDText `json:"domains"`
Notes []apiTypedIDText `json:"notes"`
Regions []apiIDText `json:"regions"`
Registers []apiIDText `json:"registers"`
SenseIds []string `json:"senseIds"`
Text string `json:"text"`
} `json:"examples"`
ID string `json:"id"`
Inflections []apiInflection `json:"inflections"`
Notes []apiTypedIDText `json:"notes"`
Pronunciations []apiPronunciation `json:"pronunciations"`
Regions []apiIDText `json:"regions"`
Registers []apiIDText `json:"registers"`
SemanticClasses []apiIDText `json:"semanticClasses"`
ShortDefinitions []string `json:"shortDefinitions"`
Subsenses []apiSense `json:"subsenses"`
Synonyms []apiWordReference `json:"synonyms"`
ThesaurusLinks []struct {
CrossReferenceMarkers []string `json:"crossReferenceMarkers"`
CrossReferences []apiTypedIDText `json:"crossReferences"`
Definitions []string `json:"definitions"`
DomainClasses []apiIDText `json:"domainClasses"`
Domains []apiIDText `json:"domains"`
Etymologies []string `json:"etymologies"`
Examples []apiComplexExample `json:"examples"`
ID string `json:"id"`
Inflections []apiInflection `json:"inflections"`
Notes []apiTypedIDText `json:"notes"`
Pronunciations []apiPronunciation `json:"pronunciations"`
Regions []apiIDText `json:"regions"`
Registers []apiIDText `json:"registers"`
SemanticClasses []apiIDText `json:"semanticClasses"`
ShortDefinitions []string `json:"shortDefinitions"`
Subsenses []apiSense `json:"subsenses"`
Synonyms []apiWordReference `json:"synonyms"`
ThesaurusLinks []struct {
EntryID string `json:"entry_id"`
SenseID string `json:"sense_id"`
} `json:"thesaurusLinks"`
VariantForms []apiVariantForm `json:"variantForms"`
}

// apiComplexExample defines the data structure for an Oxford API "example"
type apiComplexExample struct {
Definitions []string `json:"definitions"`
Domains []apiIDText `json:"domains"`
Notes []apiTypedIDText `json:"notes"`
Regions []apiIDText `json:"regions"`
Registers []apiIDText `json:"registers"`
SenseIds []string `json:"senseIds"`
Text string `json:"text"`
}

// apiPronunciation defines the data structure for an Oxford API "pronunciation"
type apiPronunciation struct {
AudioFile string `json:"audioFile"`
Expand Down Expand Up @@ -179,13 +182,9 @@ func (r *apiResponse) toResults() []source.DictionaryResult {
func (e *apiLexicalEntry) toEntry() source.DictionaryEntry {
sourceEntry := source.DictionaryEntry{}

// We filter pronunciations and potentially add them later in sub-entries...
// so the capacity can't be reasonably known here.
sourceEntry.Pronunciations = make([]string, 0)

for _, pronunciation := range e.Pronunciations {
if strings.EqualFold(phoneticNotationIPAIdentifier, pronunciation.PhoneticNotation) {
sourceEntry.Pronunciations = append(sourceEntry.Pronunciations, pronunciation.PhoneticSpelling)
sourceEntry.Pronunciations = append(sourceEntry.Pronunciations, source.Pronunciation(pronunciation.PhoneticSpelling))
}
}

Expand All @@ -197,7 +196,7 @@ func (e *apiLexicalEntry) toEntry() source.DictionaryEntry {

for _, pronunciation := range subEntry.Pronunciations {
if strings.EqualFold(phoneticNotationIPAIdentifier, pronunciation.PhoneticNotation) {
sourceEntry.Pronunciations = append(sourceEntry.Pronunciations, pronunciation.PhoneticSpelling)
sourceEntry.Pronunciations = append(sourceEntry.Pronunciations, source.Pronunciation(pronunciation.PhoneticSpelling))
}
}

Expand All @@ -218,11 +217,11 @@ func (e *apiLexicalEntry) toEntry() source.DictionaryEntry {

// toSense converts the API sense to a source.Sense
func (s *apiSense) toSense() source.Sense {
examples := make([]string, 0, len(s.Examples))
examples := make([]source.AttributedText, 0, len(s.Examples))
notes := make([]string, 0, len(s.Notes))

for _, example := range s.Examples {
examples = append(examples, example.Text)
examples = append(examples, example.toAttributedText())
}

for _, note := range s.Notes {
Expand All @@ -235,3 +234,10 @@ func (s *apiSense) toSense() source.Sense {
Notes: notes,
}
}

// toAttributedText converts the API example to a source.AttributedText
func (e *apiComplexExample) toAttributedText() source.AttributedText {
return source.AttributedText{
Text: e.Text,
}
}
72 changes: 68 additions & 4 deletions source/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
// common structures and operations for those implementations to use.
package source

import (
"fmt"
"strings"
)

// Source defines an interface for interacting with different dictionaries
type Source interface {
// Name returns the printable, human-readable name of the source.
Expand Down Expand Up @@ -31,26 +36,85 @@ type Entry struct {
type DictionaryEntry struct {
Entry

Pronunciations []string
Senses []Sense
Etymologies []string // Origins of the word
Senses []Sense
Etymologies []string // Origins of the word

Pronunciations
ThesaurusValues
}

// Pronunciations defines the structure of a collection of pronunciations
type Pronunciations []Pronunciation

// Pronunciation defines the structure of a pronunciation of a word
type Pronunciation string

// Sense defines the structure of a particular meaning of a word
type Sense struct {
Definitions []string
Examples []string
Examples []AttributedText
Notes []string

ThesaurusValues

SubSenses []Sense
}

// AttributedText defines the structure of a general text with attribution
type AttributedText struct {
Text string

Attribution
}

// Attribution defines the structure of a general attribution of a data piece
type Attribution struct {
Author string
Source string
}

// ThesaurusValues defines the structure for the thesaurus values of a word
type ThesaurusValues struct {
Synonyms []string // Words with similar meaning
Antonyms []string // Words with the opposite meaning
}

// String satisfies fmt.Stringer and dictates the string format of the value
func (p Pronunciations) String() string {
var pronunciationText string

if len(p) > 0 {
pronunciationText = p[0].String()
}

if len(p) > 1 {
var pronunciationStrings []string
for _, pronunciation := range p {
pronunciationStrings = append(pronunciationStrings, pronunciation.String())
}

pronunciationText = fmt.Sprintf("%s (%s)", pronunciationText, strings.Join(pronunciationStrings[1:], " "))
}

return pronunciationText
}

// String satisfies fmt.Stringer and dictates the string format of the value
func (p Pronunciation) String() string {
return fmt.Sprintf("/%s/", string(p))
}

// String satisfies fmt.Stringer and dictates the string format of the value
func (t AttributedText) String() string {
text := fmt.Sprintf("%q", t.Text)

if t.Author != "" {
text = fmt.Sprintf("%s - %s", text, t.Author)
}

if t.Source != "" {
text = fmt.Sprintf("%s (%s)", text, t.Source)
}

return text
}
Loading