213 lines
4.2 KiB
Go
213 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"encoding/json"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/themoeway/jmdict-go"
|
|
)
|
|
|
|
type (
|
|
StoryEntry struct {
|
|
Author string `json:"author"`
|
|
Content string `json:"content"`
|
|
ModifiedDate string `json:"modifiedDate"`
|
|
StarredCount int `json:"starredCount"`
|
|
ReportedCount int `json:"reportedCount"`
|
|
}
|
|
|
|
KanjiEntry struct {
|
|
Character string `json:"character"`
|
|
Reading string `json:"reading"`
|
|
FrameNumber int `json:"frameNumber"`
|
|
StrokeCount int `json:"strokeCount"`
|
|
Story string `json:"story"`
|
|
Stories []StoryEntry `json:"stories"`
|
|
}
|
|
|
|
TableRow = []string
|
|
Table = []TableRow
|
|
)
|
|
|
|
func injectStories(table Table, path string, heisigIndex int) error {
|
|
fp, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fp.Close()
|
|
|
|
decoder := json.NewDecoder(fp)
|
|
|
|
var characters []KanjiEntry
|
|
if err := decoder.Decode(&characters); err != nil {
|
|
return err
|
|
}
|
|
|
|
for i, row := range table {
|
|
for _, character := range characters {
|
|
if character.Character != row[heisigIndex] {
|
|
continue
|
|
}
|
|
|
|
var stories strings.Builder
|
|
for _, story := range character.Stories {
|
|
stories.WriteString(fmt.Sprintf("<span>%s</span>", story.Content))
|
|
}
|
|
|
|
row = append(row, stories.String())
|
|
table[i] = row
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func injectKanjidic(table Table, path string, heisigIndex int) error {
|
|
fp, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fp.Close()
|
|
|
|
kd, err := jmdict.LoadKanjidic(fp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for i, row := range table {
|
|
var found bool
|
|
for _, character := range kd.Characters {
|
|
if character.Literal != row[heisigIndex] {
|
|
continue
|
|
}
|
|
|
|
var (
|
|
meanings []string
|
|
kunyomi []string
|
|
onyomi []string
|
|
)
|
|
|
|
for _, reading := range character.ReadingMeaning.Readings {
|
|
switch reading.Type {
|
|
case "ja_on":
|
|
onyomi = append(onyomi, reading.Value)
|
|
case "ja_kun":
|
|
kunyomi = append(kunyomi, reading.Value)
|
|
}
|
|
}
|
|
|
|
for _, meaning := range character.ReadingMeaning.Meanings {
|
|
if meaning.Language == nil {
|
|
meanings = append(meanings, meaning.Meaning)
|
|
}
|
|
}
|
|
|
|
const seperator = " "
|
|
row = append(row, strings.Join(meanings, seperator))
|
|
row = append(row, strings.Join(kunyomi, seperator))
|
|
row = append(row, strings.Join(onyomi, seperator))
|
|
|
|
table[i] = row
|
|
found = true
|
|
}
|
|
|
|
if !found {
|
|
return errors.New("character not found")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func loadTable(path string, heisigIndex, columnLimit int) (Table, error) {
|
|
fp, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer fp.Close()
|
|
|
|
reader := csv.NewReader(fp)
|
|
reader.Comment = '#'
|
|
reader.Comma = '\t'
|
|
|
|
table, err := reader.ReadAll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for i := range table {
|
|
table[i] = table[i][:columnLimit]
|
|
if len(table[i]) < heisigIndex {
|
|
return nil, errors.New("unexpected heisig index")
|
|
}
|
|
}
|
|
|
|
return table, nil
|
|
}
|
|
|
|
func saveTable(path string, table Table) error {
|
|
fp, err := os.Create(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fp.Close()
|
|
|
|
writer := csv.NewWriter(fp)
|
|
if err := writer.WriteAll(table); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
var (
|
|
storiesPath = flag.String("stories", "", "path for stories JSON")
|
|
kanjidicPath = flag.String("kanjidic", "", "path for KANJIDIC")
|
|
heisigIndex = flag.Int("heisig", 0, "heisig index column index")
|
|
columnLimit = flag.Int("columns", 3, "column trim value")
|
|
)
|
|
|
|
flag.Usage = func() {
|
|
fmt.Fprintf(os.Stderr, "Usage: %s [options] <notes_in.txt> <notes_out.txt>\n", filepath.Base(os.Args[0]))
|
|
fmt.Fprintln(os.Stderr, "Options:")
|
|
flag.PrintDefaults()
|
|
}
|
|
|
|
flag.Parse()
|
|
|
|
args := flag.Args()
|
|
if len(args) != 2 {
|
|
flag.Usage()
|
|
os.Exit(2)
|
|
}
|
|
|
|
table, err := loadTable(args[0], *heisigIndex, *columnLimit)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if len(*storiesPath) > 0 {
|
|
if err := injectStories(table, *storiesPath, *heisigIndex); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
if len(*kanjidicPath) > 0 {
|
|
if err := injectKanjidic(table, *kanjidicPath, *heisigIndex); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
if err := saveTable(args[1], table); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|