2 linksexp -- Texinfo/XBEL/OPML/urls autogeneration from recfile bookmark
3 Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 "go.cypherpunks.ru/recfile"
32 type ByTitle []map[string][]string
34 func (a ByTitle) Len() int { return len(a) }
35 func (a ByTitle) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
36 func (a ByTitle) Less(i, j int) bool {
37 return strings.Compare(a[i]["Title"][0], a[j]["Title"][0]) < 0
41 doXBEL := flag.Bool("xbel", false, "Make XBEL")
42 doOPML := flag.Bool("opml", false, "Make OPML")
43 doURLS := flag.Bool("urls", false, "Make newsboat urls")
46 r := recfile.NewReader(os.Stdin)
50 m, err := r.NextMapWithSlice()
60 sort.Strings(m["Category"])
61 cats := strings.Join(m["Category"], " ")
62 for _, f := range m["Feed"] {
63 if strings.HasPrefix(f, "gemini://") {
64 f = "https://gemini/" + f
73 data := make([]map[string][]string, 0)
75 m, err := r.NextMapWithSlice()
85 sort.Strings(m["Category"])
86 data = append(data, m)
88 sort.Sort(ByTitle(data))
93 data := make(map[string][]map[string][]string)
95 m, err := r.NextMapWithSlice()
102 if m["%rec"] != nil {
105 sort.Strings(m["Category"])
106 if cs := m["Category"]; len(cs) == 0 {
107 data["Uncategorized"] = append(data["Uncategorized"], m)
109 for _, cat := range cs {
110 data[cat] = append(data[cat], m)
114 cats := make([]string, 0, len(data))
115 for c := range data {
116 cats = append(cats, c)
117 sort.Sort(ByTitle(data[c]))
126 fmt.Println("Updated:", time.Now().Format(time.RFC3339))
129 fmt.Println("Categories:")
130 for _, cat := range cats {
131 fmt.Printf("* %s (%d items): LinksCat%s\n", cat, len(data[cat]), cat)
133 fmt.Println("@end menu")
135 for _, cat := range cats {
136 fmt.Println("@node", "LinksCat"+cat)
137 fmt.Println("@section Links category:", cat)
138 fmt.Println("@multitable @columnfractions .05 .8 .1 .05")
139 fmt.Println("@headitem @tab @tab Other categories @tab Feed URLs")
141 for n, ent := range ents {
142 catsOther := make([]string, 0)
143 for _, c := range ent["Category"] {
145 catsOther = append(catsOther, c)
149 if len(ent["Note"]) > 0 {
150 note = "(" + strings.Trim(ent["Note"][0], " \n") + ")"
153 " @item %d @tab @url{%s,, %s} %s @tab %s @tab\n",
155 strings.ReplaceAll(ent["URL"][0], "@", "@@"),
156 strings.ReplaceAll(ent["Title"][0], "@", "@@"),
158 strings.Join(catsOther, ", "),
160 switch feeds := ent["Feed"]; len(feeds) {
162 fmt.Printf(" @emph{STATIC}\n")
166 strings.ReplaceAll(feeds[0], "@", "@@"),
169 for i, feed := range feeds {
171 " @url{%s, feed%d}\n",
172 strings.ReplaceAll(feed, "@", "@@"), i,
177 fmt.Println("@end multitable")