This repository has been archived by the owner on May 30, 2021. It is now read-only.
/
decode.go
96 lines (76 loc) · 2.31 KB
/
decode.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package gobibtex
import (
"errors"
"regexp"
"strings"
)
// Parse entry name
func parseEntry(bibstring string) (entry string, err error) {
listEntry := []string{"article", "book", "booklet", "conference", "inbook", "incollection", "inproceedings", "manual", "mastersthesis", "misc", "phdthesis", "proceedings", "techreport", "unpublished"}
for _, entry := range listEntry {
r := regexp.MustCompile("^@" + entry + "*{")
if r.MatchString(bibstring) {
return entry, nil
}
}
return "", errors.New("Entry not found")
}
// Parse fields
func parseFields(bibstring string) (fields map[string]string) {
listField := []string{"address", "annote", "author", "booktitle", "chapter", "crossref", "edition", "editor", "howpublished", "institution", "journal", "key", "month", "note", "number", "organization", "pages", "publisher", "school", "series", "title", "type", "volume", "year"}
fields = make(map[string]string)
for _, field := range listField {
r := regexp.MustCompile(field + `[\s]*=[\s]*[{"][^}]*["}][},]`)
if !r.MatchString(bibstring) {
continue
}
val := r.FindString(bibstring)
// trim
val = val[len(field):]
val = strings.TrimSpace(val)
val = strings.Trim(val, "=")
val = strings.TrimSpace(val)
val = strings.Trim(val, ",")
val = strings.Trim(val, "}")
val = strings.Trim(val, "}")
val = strings.Trim(val, "{")
val = strings.Trim(val, "{")
val = strings.Trim(val, `"`)
fields[field] = val
}
return fields
}
// Parse bibtex name
func parseName(bibstring string) (name string) {
ix1 := strings.Index(bibstring, "{")
ix2 := strings.Index(bibstring, ",")
name = bibstring[ix1+1 : ix2]
return name
}
// Parse authors
func parseAuthors(authorString string) (authors []string) {
s := strings.Split(authorString, " and ")
for i, v := range s {
s[i] = strings.TrimSpace(v)
}
return s
}
// Decode bibtex string to map.
func Decode(bibstring string) (bibmap map[string]interface{}, err error) {
entry, err := parseEntry(bibstring)
if err != nil {
return nil, err
}
name := parseName(bibstring)
fields := parseFields(bibstring)
bibmap = make(map[string]interface{})
bibmap["entry"] = entry
bibmap["name"] = name
for k, v := range fields {
bibmap[k] = v
}
if _, ok := bibmap["author"]; ok {
bibmap["author"] = parseAuthors(bibmap["author"].(string))
}
return bibmap, err
}