Просмотр исходного кода

Make linter happy

Some doc strings, namings and slight code adjustments.  `go fmt` is
still pretty nice, especially if it's integrated into 'yer editor!
Luna Stadler лет назад: 4
Родитель
Сommit
698b99346e
1 измененных файлов с 41 добавлено и 31 удалено
  1. 41 31
      go/blog/blog.go

+ 41 - 31
go/blog/blog.go

1
// Command blog renders a YAML file to a little HTML blog.
2
//
3
// Feel free to adapt it and use it in your setup, if you want your own
4
// personal digital writing implement.
1
package main
5
package main
2
6
3
import (
7
import (
22
	"gopkg.in/yaml.v2"
26
	"gopkg.in/yaml.v2"
23
)
27
)
24
28
29
// Post is a single post, title, tags and all.
30
//
31
// It contains all information to get rendered by something, as determined by
32
// the `Type`.
25
type Post struct {
33
type Post struct {
26
	Id      string   `yaml:"id"`
34
	ID      string   `yaml:"id"`
27
	Title   string   `yaml:"title"`
35
	Title   string   `yaml:"title"`
28
	URL     string   `yaml:"url"`
36
	URL     string   `yaml:"url"`
29
	Content string   `yaml:"content"`
37
	Content string   `yaml:"content"`
32
	Type    string   `yaml:"type"`
40
	Type    string   `yaml:"type"`
33
}
41
}
34
42
43
// Options are options that can be specified in the YAML file itself or on the
44
// commandline, to control how the output is done.
35
type Options struct {
45
type Options struct {
36
	WriteBack      bool   `yaml:"write_back"`
46
	WriteBack      bool   `yaml:"write_back"`
37
	HashIds        bool   `yaml:"hash_ids"`
47
	HashIDs        bool   `yaml:"hash_ids"`
38
	Reverse        bool   `yaml:"reverse"`
48
	Reverse        bool   `yaml:"reverse"`
39
	Css            string `yaml:"css"`
49
	CSS            string `yaml:"css"`
40
	NoDefaultStyle bool   `yaml:"no_default_style"`
50
	NoDefaultStyle bool   `yaml:"no_default_style"`
41
	Title          string `yaml:"title"`
51
	Title          string `yaml:"title"`
42
	After          string `yaml:"after"`
52
	After          string `yaml:"after"`
142
152
143
func init() {
153
func init() {
144
	flag.BoolVar(&flags.WriteBack, "write-back", false, "Rewrite the YAML file with the generated ids")
154
	flag.BoolVar(&flags.WriteBack, "write-back", false, "Rewrite the YAML file with the generated ids")
145
	flag.BoolVar(&flags.HashIds, "hash-ids", false, "Use hash-based post ids")
155
	flag.BoolVar(&flags.HashIDs, "hash-ids", false, "Use hash-based post ids")
146
	flag.BoolVar(&flags.Reverse, "reverse", false, "Reverse the order of the articles in the file")
156
	flag.BoolVar(&flags.Reverse, "reverse", false, "Reverse the order of the articles in the file")
147
	flag.StringVar(&flags.Css, "css", "", "Use custom `css` styles")
157
	flag.StringVar(&flags.CSS, "css", "", "Use custom `css` styles")
148
	flag.BoolVar(&flags.NoDefaultStyle, "no-default-style", false, "Don't use the default styles")
158
	flag.BoolVar(&flags.NoDefaultStyle, "no-default-style", false, "Don't use the default styles")
149
	flag.BoolVar(&flags.PrintDefaultStyle, "print-default-style", false, "Print the default styles")
159
	flag.BoolVar(&flags.PrintDefaultStyle, "print-default-style", false, "Print the default styles")
150
	flag.StringVar(&flags.Title, "title", "A blog", "Custom `title` to use")
160
	flag.StringVar(&flags.Title, "title", "A blog", "Custom `title` to use")
210
			case "write-back":
220
			case "write-back":
211
				flags.WriteBack = opts.WriteBack
221
				flags.WriteBack = opts.WriteBack
212
			case "hash-ids":
222
			case "hash-ids":
213
				flags.HashIds = opts.HashIds
223
				flags.HashIDs = opts.HashIDs
214
			case "reverse":
224
			case "reverse":
215
				flags.Reverse = opts.Reverse
225
				flags.Reverse = opts.Reverse
216
			case "css":
226
			case "css":
217
				flags.Css = opts.Css
227
				flags.CSS = opts.CSS
218
			case "no-default-style":
228
			case "no-default-style":
219
				flags.NoDefaultStyle = opts.NoDefaultStyle
229
				flags.NoDefaultStyle = opts.NoDefaultStyle
220
			case "title":
230
			case "title":
261
</head>
271
</head>
262
272
263
<body>
273
<body>
264
`, template.HTMLEscapeString(flags.Title), defaultStyle, flags.Css)
274
`, template.HTMLEscapeString(flags.Title), defaultStyle, flags.CSS)
265
275
266
	if flags.Reverse {
276
	if flags.Reverse {
267
		l := len(posts)
277
		l := len(posts)
274
284
275
	tags := map[string]bool{}
285
	tags := map[string]bool{}
276
	for i, post := range posts {
286
	for i, post := range posts {
277
		if post.Id == "" {
278
			posts[i].Id = generateId(post)
287
		if post.ID == "" {
288
			posts[i].ID = generateID(post)
279
			post = posts[i]
289
			post = posts[i]
280
		}
290
		}
281
291
310
			case (u.Host == "youtube.com" || u.Host == "www.youtube.com") && u.Query().Get("v") != "":
320
			case (u.Host == "youtube.com" || u.Host == "www.youtube.com") && u.Query().Get("v") != "":
311
				provider = "youtube"
321
				provider = "youtube"
312
				post.URL = fmt.Sprintf("https://www.youtube.com/embed/%s", u.Query().Get("v"))
322
				post.URL = fmt.Sprintf("https://www.youtube.com/embed/%s", u.Query().Get("v"))
313
			case u.Host == "vimeo.com" && getVimeoId(u.Path) != "":
323
			case u.Host == "vimeo.com" && getVimeoID(u.Path) != "":
314
				provider = "vimeo"
324
				provider = "vimeo"
315
				post.URL = fmt.Sprintf("https://player.vimeo.com/video/%s", getVimeoId(u.Path))
325
				post.URL = fmt.Sprintf("https://player.vimeo.com/video/%s", getVimeoID(u.Path))
316
			default:
326
			default:
317
				exit(fmt.Errorf("unsupported video url '%s'", post.URL))
327
				exit(fmt.Errorf("unsupported video url '%s'", post.URL))
318
			}
328
			}
331
	}
341
	}
332
342
333
	sortedTags := []string{}
343
	sortedTags := []string{}
334
	for tag, _ := range tags {
344
	for tag := range tags {
335
		sortedTags = append(sortedTags, tag)
345
		sortedTags = append(sortedTags, tag)
336
	}
346
	}
337
	sort.Strings(sortedTags)
347
	sort.Strings(sortedTags)
516
	<header>
526
	<header>
517
		{{- if .Title }}
527
		{{- if .Title }}
518
		<h1>{{ .Title }}</h1>{{ end }}
528
		<h1>{{ .Title }}</h1>{{ end }}
519
		<a class="permalink" href="#{{ .Id }}">∞</a>
529
		<a class="permalink" href="#{{ .ID }}">∞</a>
520
		{{- if .Date }}
530
		{{- if .Date }}
521
		<time>{{ .Date }}</time>{{ end }}
531
		<time>{{ .Date }}</time>{{ end }}
522
	</header>
532
	</header>
533
543
534
var shellTmpl = template.Must(baseTmpl.New("shell").
544
var shellTmpl = template.Must(baseTmpl.New("shell").
535
	Funcs(funcs).Parse(`
545
	Funcs(funcs).Parse(`
536
<article id="{{ .Id }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
546
<article id="{{ .ID }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
537
	<header>
547
	<header>
538
		<h1><code class="language-shell">{{ .Title }}</code></h1>
548
		<h1><code class="language-shell">{{ .Title }}</code></h1>
539
		<a class="permalink" href="#{{ .Id }}">∞</a>
549
		<a class="permalink" href="#{{ .ID }}">∞</a>
540
		{{- if .Date }}
550
		{{- if .Date }}
541
		<time>{{ .Date }}</time>{{ end }}
551
		<time>{{ .Date }}</time>{{ end }}
542
	</header>
552
	</header>
553
563
554
var linkTmpl = template.Must(baseTmpl.New("link").
564
var linkTmpl = template.Must(baseTmpl.New("link").
555
	Funcs(funcs).Parse(`
565
	Funcs(funcs).Parse(`
556
<article id="{{ .Id }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
566
<article id="{{ .ID }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
557
	<header>
567
	<header>
558
		<h1><a href="{{ .URL }}">{{ .Title }}</a></h1>
568
		<h1><a href="{{ .URL }}">{{ .Title }}</a></h1>
559
		<a class="permalink" href="#{{ .Id }}">∞</a>
569
		<a class="permalink" href="#{{ .ID }}">∞</a>
560
		{{- if .Date }}
570
		{{- if .Date }}
561
		<time>{{ .Date }}</time>{{ end }}
571
		<time>{{ .Date }}</time>{{ end }}
562
	</header>
572
	</header>
573
583
574
var imageTmpl = template.Must(baseTmpl.New("image").
584
var imageTmpl = template.Must(baseTmpl.New("image").
575
	Funcs(funcs).Parse(`
585
	Funcs(funcs).Parse(`
576
<article id="{{ .Id }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
586
<article id="{{ .ID }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
577
	{{- template "title" . }}
587
	{{- template "title" . }}
578
	<img src="{{ safe_url .URL }}" />
588
	<img src="{{ safe_url .URL }}" />
579
	{{- if .Content }}
589
	{{- if .Content }}
589
599
590
var songTmpl = template.Must(baseTmpl.New("song").
600
var songTmpl = template.Must(baseTmpl.New("song").
591
	Funcs(funcs).Parse(`
601
	Funcs(funcs).Parse(`
592
<article id="{{ .Id }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
602
<article id="{{ .ID }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
593
	{{- template "title" . }}
603
	{{- template "title" . }}
594
	<audio src="{{ safe_url .URL }}" controls>
604
	<audio src="{{ safe_url .URL }}" controls>
595
		Your browser can't play {{ .URL }}.
605
		Your browser can't play {{ .URL }}.
607
617
608
var textTmpl = template.Must(baseTmpl.New("text").
618
var textTmpl = template.Must(baseTmpl.New("text").
609
	Funcs(funcs).Parse(`
619
	Funcs(funcs).Parse(`
610
<article id="{{ .Id }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
620
<article id="{{ .ID }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
611
	{{- template "title" . }}
621
	{{- template "title" . }}
612
	{{- if .Content }}
622
	{{- if .Content }}
613
623
621
`))
631
`))
622
632
623
var videoTmpl = template.Must(baseTmpl.New("video").Parse(`
633
var videoTmpl = template.Must(baseTmpl.New("video").Parse(`
624
<article id="{{ .Id }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
634
<article id="{{ .ID }}" class="{{ .Type }}" {{- if .Tags }} data-tags="{{ json .Tags }}"{{ end }}>
625
	{{- template "title" . }}
635
	{{- template "title" . }}
626
	{{ if (eq .Provider "youtube" "vimeo") -}}
636
	{{ if (eq .Provider "youtube" "vimeo") -}}
627
	<iframe width="560" height="315" src="{{ safe_url .URL }}" frameborder="0" allowfullscreen loading="lazy"></iframe>
637
	<iframe width="560" height="315" src="{{ safe_url .URL }}" frameborder="0" allowfullscreen loading="lazy"></iframe>
651
	os.Exit(1)
661
	os.Exit(1)
652
}
662
}
653
663
654
func generateId(p Post) string {
655
	if flags.HashIds {
656
		return hashId(p)
664
func generateID(p Post) string {
665
	if flags.HashIDs {
666
		return hashID(p)
657
	}
667
	}
658
	return slugId(p)
668
	return slugID(p)
659
}
669
}
660
670
661
func hashId(p Post) string {
671
func hashID(p Post) string {
662
	h := md5.New()
672
	h := md5.New()
663
	io.WriteString(h, p.Title)
673
	io.WriteString(h, p.Title)
664
	io.WriteString(h, p.Content)
674
	io.WriteString(h, p.Content)
666
	return hex.EncodeToString(h.Sum(nil))
676
	return hex.EncodeToString(h.Sum(nil))
667
}
677
}
668
678
669
func randomId() string {
679
func randomID() string {
670
	buf := make([]byte, 16)
680
	buf := make([]byte, 16)
671
	_, err := rand.Read(buf)
681
	_, err := rand.Read(buf)
672
	if err != nil {
682
	if err != nil {
678
688
679
var usedSlugs = map[string]int{}
689
var usedSlugs = map[string]int{}
680
690
681
func slugId(p Post) string {
691
func slugID(p Post) string {
682
	slug := toSlug(p.Title)
692
	slug := toSlug(p.Title)
683
	n, ok := usedSlugs[slug]
693
	n, ok := usedSlugs[slug]
684
	if ok {
694
	if ok {
685
		n += 1
695
		n++
686
	} else {
696
	} else {
687
		n = 1
697
		n = 1
688
	}
698
	}
715
	return strings.Trim(s, "-")
725
	return strings.Trim(s, "-")
716
}
726
}
717
727
718
func getVimeoId(p string) string {
728
func getVimeoID(p string) string {
719
	i := strings.LastIndex(p, "/")
729
	i := strings.LastIndex(p, "/")
720
	if i == -1 || len(p) == i+1 {
730
	if i == -1 || len(p) == i+1 {
721
		return ""
731
		return ""