func NewJSONLRenderer() Renderer {
	return &JSONRenderer{
		render: func(out io.Writer, st *papers.Stats, unread, read papers.AggPapers) {
			log.Print("formatting gmail messages in JSONL")
			encoder := json.NewEncoder(out)
			for _, title := range papers.SortedKeys(unread) {
				encoder.Encode(unread[title])
			}
			for _, title := range papers.SortedKeys(read) {
				encoder.Encode(read[title])
			}
		},
	}
}
NewJSONLRenderer factory for Renderer in JSONL format.
package templates
import (
	"bytes"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"log"
	"strconv"
	"time"
	"github.com/bzz/scholar-alert-digest/papers"
	"gitlab.com/golang-commonmark/markdown"
)
var (
	RootLayout = template.Must(template.New("layout").Parse(`
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="icon" href="http://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/240/apple/232/page-with-curl_1f4c3.png">
  <base target="_blank">
  <title>{{ template "title" }}</title>
  <style>{{ template "style" }}</style>
</head>
<body>{{ template "body" . }}</body>
</html>
`))
	MdTemplText = `# Google Scholar Alert Digest
**Date**: {{.Date}}
**Unread emails**: {{.UnreadEmails}}
**Paper titles**: {{.TotalPapers}}
**Uniq paper titles**: {{.UniqPapers}}
## New papers
{{ range $title := sortedKeys .Papers }}
   {{ $paper := index $.Papers . }}
 - [{{ $paper.Title }}]({{ $paper.URL }}){{if $paper.Author}}, <i>{{ $paper.Author }}</i>{{end}} {{ template "refs" $paper }}
   {{- if $paper.Abstract.FirstLine }}
   <details>
     <summary>{{ $paper.Abstract.FirstLine }}</summary>
     <div>{{ $paper.Abstract.Rest }}</div>
   </details>
   {{ end }}
{{ end }}
`
	refsMdTemplateText = `
{{ define "refs" -}}
({{ if eq (len .Refs) 0}}{{ .Freq }}{{end}}
{{- if gt (len .Refs) 1}}{{ .Freq }}: {{end}}
{{- range $i, $ref := .Refs}}
	{{- if $i}}, {{end}}
	{{- anchorHTML $ref.ID $ref.Title $i -}}
{{- end}})
{{- end}}
`
	CompactMdTemplText = `# Google Scholar Alert Digest
**Date**: {{.Date}}
**Unread emails**: {{.UnreadEmails}}
**Paper titles**: {{.TotalPapers}}
**Uniq paper titles**: {{.UniqPapers}}
## New papers
{{ range $title := sortedKeys .Papers }}
   {{ $paper := index $.Papers . }}
 - <details onclick="document.activeElement.blur();">
	 <summary><a href="{{ $paper.URL }}">{{ $paper.Title }}</a>, <i>{{ $paper.Author }}</i> {{ template "refs" $paper }}</summary>
	 <div class="wide">
     {{- if $paper.Abstract.FirstLine }}
	   <div>{{$paper.Abstract.FirstLine}} {{$paper.Abstract.Rest}}</div>
	 {{- end }}
	 </div>
   </details>
{{ end }}
`
	ReadMdTemplText = `## Old papers
<details id="archive">
  <summary>Archive</summary>
{{ range $title := sortedKeys . }}
  {{ $paper := index $ . }}
  - [{{ $paper.Title }}]({{ $paper.URL }})
    {{- if $paper.Abstract.FirstLine }}
    <details>
      <summary>{{$paper.Abstract.FirstLine}}</summary>{{$paper.Abstract.Rest}}
    </details>
    {{ end }}
{{ end }}
</details>
`
	CompatStyle = `
ul { list-style-type: none; margin: 0; padding: 0 0 0 20px; }
#archive>ul {list-style-type: circle; }
.wide { max-width:60%; margin-left: 1em; padding: 0.2em 0 0.5em 0; }
`
)
type Renderer interface {
	Render(out io.Writer, st *papers.Stats, unread, read papers.AggPapers)
}
type JSONRenderer struct {
	render func(io.Writer, *papers.Stats, papers.AggPapers, papers.AggPapers)
}
func (r *JSONRenderer) Render(out io.Writer, st *papers.Stats, unread, read papers.AggPapers) {
	r.render(out, st, unread, read)
}
func NewJSONRenderer() Renderer {
	return &JSONRenderer{
		render: func(out io.Writer, st *papers.Stats, unread, read papers.AggPapers) {
			log.Printf("formatting gmail messages in JSON")
			sr := []*papers.Paper{}
			for _, title := range papers.SortedKeys(read) {
				sr = append(sr, read[title])
			}
			su := []*papers.Paper{}
			for _, title := range papers.SortedKeys(unread) {
				su = append(su, unread[title])
			}
			all := map[string]interface{}{
				"read": map[string]interface{}{
					"papers": sr,
				},
				"unread": map[string]interface{}{
					"papers": su,
					"stats": map[string]interface{}{
						"time":     time.Now().Format(time.RFC3339),
						"messages": st.Msgs,
						"papers":   st.Titles,
					},
				},
			}
			encoder := json.NewEncoder(out)
			encoder.Encode(all)
		},
	}
}