diff options
author | Jordan <me@jordan.im> | 2022-01-01 19:43:19 -0700 |
---|---|---|
committer | Jordan <me@jordan.im> | 2022-01-01 19:43:19 -0700 |
commit | 4f1178fc2a3e5865c2fb1c16c83fc1abb15484f9 (patch) | |
tree | ecec1f79a373cb2331de9b8011177ae2db9d039b | |
parent | 8401a6bdeec321920550f813a1c7843ed6e66a44 (diff) | |
download | crane-4f1178fc2a3e5865c2fb1c16c83fc1abb15484f9.tar.gz crane-4f1178fc2a3e5865c2fb1c16c83fc1abb15484f9.zip |
crane, http, util: housekeeping, performance improvements, styling
-rw-r--r-- | crane.go | 13 | ||||
-rw-r--r-- | http.go | 98 | ||||
-rw-r--r-- | templates/admin-edit.html | 105 | ||||
-rw-r--r-- | templates/admin.html | 74 | ||||
-rw-r--r-- | templates/index.html | 23 | ||||
-rw-r--r-- | templates/layout.html | 280 | ||||
-rw-r--r-- | templates/list.html | 65 | ||||
-rw-r--r-- | util.go | 84 |
8 files changed, 303 insertions, 439 deletions
@@ -36,7 +36,6 @@ var ( user string pass string buildPrefix string - templateDir string ) type Contributor struct { @@ -639,18 +638,6 @@ func main() { panic(errors.New("Host flag could not be parsed; is it an IP address?")) } - // prefer system-installed template assets over project-local paths - if _, err := os.Stat(filepath.Join(buildPrefix, - "/share/crane/templates")); err != nil { - dir, err := filepath.Abs(filepath.Dir(os.Args[0])) - if err != nil { - log.Fatal(err) - } - templateDir = filepath.Join(dir, "templates") - } else { - templateDir = filepath.Join(buildPrefix, "/share/crane/templates") - } - http.HandleFunc("/", papers.IndexHandler) http.HandleFunc("/admin/", papers.AdminHandler) http.HandleFunc("/admin/edit/", papers.EditHandler) @@ -2,50 +2,74 @@ package main import ( "fmt" - "net/http" "html/template" + "log" + "net/http" "os" "path/filepath" "strings" ) +var templateDir = getTemplateDir() + +var indexTemp = template.Must(template.ParseFiles( + filepath.Join(templateDir, "layout.html"), + filepath.Join(templateDir, "index.html"), + filepath.Join(templateDir, "list.html"), +)) +var adminTemp = template.Must(template.ParseFiles( + filepath.Join(templateDir, "admin.html"), + filepath.Join(templateDir, "layout.html"), + filepath.Join(templateDir, "list.html"), +)) +var editTemp = template.Must(template.ParseFiles( + filepath.Join(templateDir, "admin-edit.html"), + filepath.Join(templateDir, "layout.html"), + filepath.Join(templateDir, "list.html"), +)) + +func cat(cat string) string { + + return strings.Replace(cat, "-", "‑", -1) +} + +// getTemplateDir returns the absolute path of the templates directory, +// preferring system-installed assets over the project-local path +func getTemplateDir() string { + + if _, err := os.Stat(filepath.Join(buildPrefix, + "/share/crane/templates")); err != nil { + dir, err := filepath.Abs(filepath.Dir(os.Args[0])) + if err != nil { + log.Fatal(err) + } + return filepath.Join(dir, "templates") + } else { + return filepath.Join(buildPrefix, "/share/crane/templates") + } +} + // IndexHandler renders the index of papers stored in papers.Path func (papers *Papers) IndexHandler(w http.ResponseWriter, r *http.Request) { + // catch-all for paths unhandled by direct http.HandleFunc calls if r.URL.Path != "/" { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } - t, _ := template.ParseFiles(filepath.Join(templateDir, "layout.html"), - filepath.Join(templateDir, "index.html"), - filepath.Join(templateDir, "list.html"), - ) - papers.RLock() - res := Resp{ - Papers: *papers, - } - papers.RUnlock() - - t.Execute(w, &res) + res := Resp{Papers: *papers} + indexTemp.Execute(w, &res) } // AdminHandler renders the index of papers stored in papers.Path with // additional forms to modify the collection (add, delete, rename...) func (papers *Papers) AdminHandler(w http.ResponseWriter, r *http.Request) { - t, _ := template.ParseFiles(filepath.Join(templateDir, "admin.html"), - filepath.Join(templateDir, "layout.html"), - filepath.Join(templateDir, "list.html"), - ) - papers.RLock() - res := Resp{ - Papers: *papers, - } - papers.RUnlock() + res := Resp{Papers: *papers} if user != "" && pass != "" { username, password, ok := r.BasicAuth() if ok && user == username && pass == password { - t.Execute(w, &res) + adminTemp.Execute(w, &res) } else { w.Header().Add("WWW-Authenticate", `Basic realm="Please authenticate"`) @@ -53,23 +77,15 @@ func (papers *Papers) AdminHandler(w http.ResponseWriter, r *http.Request) { http.StatusUnauthorized) } } else { - t.Execute(w, &res) + adminTemp.Execute(w, &res) } } // EditHandler renders the index of papers stored in papers.Path, prefixing // a checkbox to each unique paper and category for modification func (papers *Papers) EditHandler(w http.ResponseWriter, r *http.Request) { - t, _ := template.ParseFiles(filepath.Join(templateDir, "admin-edit.html"), - filepath.Join(templateDir, "layout.html"), - filepath.Join(templateDir, "list.html"), - ) - papers.RLock() - res := Resp{ - Papers: *papers, - } - papers.RUnlock() + res := Resp{Papers: *papers} if user != "" && pass != "" { username, password, ok := r.BasicAuth() if !ok || user != username || pass != password { @@ -82,10 +98,9 @@ func (papers *Papers) EditHandler(w http.ResponseWriter, r *http.Request) { } if err := r.ParseForm(); err != nil { res.Status = err.Error() - t.Execute(w, &res) + editTemp.Execute(w, &res) return } - if action := r.FormValue("action"); action == "delete" { for _, paper := range r.Form["paper"] { if res.Status != "" { @@ -135,15 +150,12 @@ func (papers *Papers) EditHandler(w http.ResponseWriter, r *http.Request) { } } } - t.Execute(w, &res) + editTemp.Execute(w, &res) } // AddHandler provides support for new paper processing and category addition func (papers *Papers) AddHandler(w http.ResponseWriter, r *http.Request) { - t, _ := template.ParseFiles(filepath.Join(templateDir, "admin.html"), - filepath.Join(templateDir, "layout.html"), - filepath.Join(templateDir, "list.html"), - ) + if user != "" && pass != "" { username, password, ok := r.BasicAuth() if !ok || user != username || pass != password { @@ -161,7 +173,6 @@ func (papers *Papers) AddHandler(w http.ResponseWriter, r *http.Request) { // sanitize input; we use the category to build the path used to save // papers nc = strings.Trim(strings.Replace(nc, "..", "", -1), "/.") - res := Resp{} // paper download, both required fields populated @@ -204,15 +215,13 @@ func (papers *Papers) AddHandler(w http.ResponseWriter, r *http.Request) { res.Status = fmt.Sprintf("category %q added successfully", nc) } } - papers.RLock() res.Papers = *papers - papers.RUnlock() - - t.Execute(w, &res) + adminTemp.Execute(w, &res) } // DownloadHandler serves saved papers up for download func (papers *Papers) DownloadHandler(w http.ResponseWriter, r *http.Request) { + paper := strings.TrimPrefix(r.URL.Path, "/download/") category := filepath.Dir(paper) @@ -241,4 +250,3 @@ func (papers *Papers) DownloadHandler(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, papers.List[category][paper].PaperPath) } } - diff --git a/templates/admin-edit.html b/templates/admin-edit.html index 5bd4fa1..d8805f9 100644 --- a/templates/admin-edit.html +++ b/templates/admin-edit.html @@ -1,32 +1,40 @@ {{ template "layout.html" . }} {{ define "content" }} -<p>{{ .Status }}</p> -<table id='header'> +<table class="admin" id="header"> + <tr> + <td> + {{ if .LastPaperDL }} + {{ .Status }} (<a style="text-decoration: underline;" href="/download/{{ .LastPaperDL }}">download</a>) + {{ else }} + {{ .Status }} + {{ end }} + </td> + </tr> <tr> {{ $categoryCount := len .Papers.List }} {{ if gt $categoryCount 0 }} - <td class='inpt'> + <td> <form method='post' action='/admin/edit/'> - <input type="text" id="rename-category" name="rename-to" placeholder="Mathematics"> + <input type="text" id="rename-category" name="rename-to" placeholder="Mathematics"/> <select class="sel" name="rename-category" id="category"> {{ range $category, $papers := .Papers.List }} <option value="{{ $category }}">{{ $category }}</option> {{ end }} </select> - <input class="btn" type="submit" value="Rename Category"> + <input type="submit" value="Rename Category"/> </form> </td> {{ end }} </tr> </table> -<div class="cat"> - <span>{{ range $category, $paper := .Papers.List }}<span class="nowrap">[<a href="#{{ $category }}">{{ $category }}</a>]</span> {{ end }}</span> +<div class="cat-cont"> + <div class="cat"> + {{ range $category, $paper := .Papers.List }} + <span class="cat">[<a href="#{{ $category }}">{{ $category }}</a>]</span> + {{ end }} + </div> </div> -<table class='tabs'> - <tr> - <td><a class='active' href='/admin/'>Back</a></td> - </tr> -</table> +<p class="Pp"><a class='active' href='/admin/'>Back</a></p> <div class='content'> {{ if gt $categoryCount 0 }} <form method='post' action='/admin/edit/'> @@ -41,43 +49,76 @@ {{ end }} </optgroup> </select> - <input class="btn" type="submit" value="Save" /> + <input type="submit" value="Save" /> </div> -<div class='papers nowrap list'> +<div> {{ range $category, $papers := .Papers.List }} {{ $paperCount := len $papers }} - <div class="papersection"> - <input type="checkbox" id="{{ $category }}" name="category" value="{{ $category }}"> - <label for="{{ $category }}"><span class='papersection' id='{{ $category }}'>{{ $category }}</span></label> - </div> + <input type="checkbox" id="{{ $category }}" name="category" value="{{ $category }}"/> + <label for="{{ $category }}"> + <span id='{{ $category }}'> + <a class="permalink" href="#{{ $category }}">{{ $category }}</a> + </span> + </label> {{ range $path, $paper := $papers }} - <ul> - <li> + <div class="paper"> {{ if $paper.Meta.Title }} - <span class="title"><input type="checkbox" id="{{ $path }}" name="paper" value="{{ $path }}"> <a href='/download/{{ $path }}' title='{{ $paper.Meta.Title }}'>{{ $paper.Meta.Title }}</a></input></span><br> + <span class="title"> + <input type="checkbox" id="{{ $path }}" name="paper" value="{{ $path }}"/> + <a href='/download/{{ $path }}' title='{{ $paper.Meta.Title }}'>{{ $paper.Meta.Title }}</a> + </span> + <br /> {{ else }} - <span class="title"><input type="checkbox" id="{{ $path }}" name="paper" value="{{ $path }}"><label for="{{ $path }}"> <a href='/download/{{ $path }}' title='{{ $paper.PaperName }}'>{{ $paper.PaperName }}</a></label></span><br> + <span class="title"> + <input type="checkbox" id="{{ $path }}" name="paper" value="{{ $path }}"/> + <label for="{{ $path }}"> + <a href='/download/{{ $path }}' title='{{ $paper.PaperName }}'>{{ $paper.PaperName }}</a> + </label> + </span> + <br /> {{ end }} {{ $contCount := len $paper.Meta.Contributors }}{{ if ge $contCount 1 }} - <span class="authors">{{ range $index, $contributor := $paper.Meta.Contributors }}{{if $index}}, {{end}}{{ $contributor.FirstName }} {{ $contributor.LastName }}{{end}}</span><br> + <span class="authors"> + {{- range $index, $contributor := $paper.Meta.Contributors -}} + {{- if $index }}, {{ end }} + {{- $contributor.FirstName }} {{ $contributor.LastName -}} + {{- end -}} + </span> + <br /> {{ end }} {{ $hasVal := false }} - {{ if $paper.Meta.PubYear }}{{ $hasVal = true }}<span class="year">{{ $paper.Meta.PubYear }}</span>{{ end }} - - {{ if $paper.Meta.DOI }}{{ if $hasVal }}- {{end}}<span class="doi"><a href="https://doi.org/{{ $paper.Meta.DOI }}">{{ $paper.Meta.DOI }}</a></span> + {{ if $paper.Meta.PubYear }}{{ $hasVal = true }} + <span class="year">{{ $paper.Meta.PubYear }}</span> + {{ end }} - {{ else if $paper.Meta.ArxivID }}{{ if $hasVal }}- {{ end }}<span class="doi"><a href="https://arxiv.org/abs/{{ $paper.Meta.ArxivID }}">{{ $paper.Meta.ArxivID }}</span> - {{ else if $paper.Meta.Resource }}{{ if $hasVal }}- {{ end }}<span class="doi"><a href="{{ $paper.Meta.Resource }}">{{ $paper.Meta.Resource }}</a></span>{{ end }} + {{ if $paper.Meta.DOI }}{{ if $hasVal }}- {{end}} + <span class="doi"> + <a href="https://doi.org/{{ $paper.Meta.DOI }}">{{ $paper.Meta.DOI }}</a> + </span> + {{ else if $paper.Meta.ArxivID }} + {{ if $hasVal }}- {{ end }} + <span class="doi"> + <a href="https://arxiv.org/abs/{{ $paper.Meta.ArxivID }}">{{ $paper.Meta.ArxivID }}</a> + </span> + {{ else if $paper.Meta.Resource }} + {{ if $hasVal }}- {{ end }} + <span class="doi"> + <a href="{{ $paper.Meta.Resource }}">{{ $paper.Meta.Resource }}</a> + </span> + {{ end }} - {{ if $paper.Meta.Journal }}{{ if $hasVal }}- {{ end }}<span class="journal">{{ $paper.Meta.Journal }}</span>{{ end }} + {{ if $paper.Meta.Journal }} + {{ if $hasVal }}- {{ end }} + <span class="journal">{{ $paper.Meta.Journal }} + </span> + {{ end }} - </li> - </ul> + </div> {{ end }} - <hr> {{ end }} +</div> {{ end }} </form></div> {{ end }} diff --git a/templates/admin.html b/templates/admin.html index 8573e23..fb3a3d2 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -1,51 +1,55 @@ {{ template "layout.html" . }} {{ define "content" }} -{{ if .LastPaperDL }} -<p>{{ .Status }} (<a style="text-decoration: underline;" href="/download/{{ .LastPaperDL }}">download</a>)</p> -{{ else }} -<p>{{ .Status }}</p> -{{ end }} -<table id='header'> +<table class="admin"> + <tr> + <td> + {{ if .LastPaperDL }} + {{ .Status }} (<a style="text-decoration: underline;" href="/download/{{ .LastPaperDL }}">download</a>) + {{ else }} + {{ .Status }} + {{ end }} + </td> + </tr> <tr> - <td class='inpt'> - <form method='post' action='/admin/add/'> - <input type='text' name='new-category' placeholder="Mathematics" value=''/> - <input class='btn' type="submit" value="New Category" /> + <td> + <form method='post' action='/admin/add/'> + <input type='text' name='new-category' placeholder="Mathematics" value=''/> + <input type="submit" value="New Category" /> </form> - </td> + </td> </tr> {{ $categoryCount := len .Papers.List }} {{ if gt $categoryCount 0 }} <tr> - <td class='inpt'> - <form method='post' action='/admin/add/'> - <input type='text' name='dl-paper' placeholder="URL or DOI" value=''/> - <select class="sel" name="dl-category" id="category"> - {{ $lastUsedCategory := .LastUsedCategory }} - {{ if $lastUsedCategory }} - <option value="{{ .LastUsedCategory }}">{{ $lastUsedCategory }}</option> - {{ end }} - {{ range $category, $papers := .Papers.List }} - {{ if ne $category $lastUsedCategory }} - <option value="{{ $category }}">{{ $category }}</option> - {{ end }} - {{ end }} - </select> - <input class="btn" type="submit" value="Download" /> - </form> - </td> + <td> + <form method='post' action='/admin/add/'> + <input type='text' name='dl-paper' placeholder="URL or DOI" value=''/> + <select class="sel" name="dl-category" id="category"> + {{ $lastUsedCategory := .LastUsedCategory }} + {{ if $lastUsedCategory }} + <option value="{{ .LastUsedCategory }}">{{ $lastUsedCategory }}</option> + {{ end }} + {{ range $category, $papers := .Papers.List }} + {{ if ne $category $lastUsedCategory }} + <option value="{{ $category }}">{{ $category }}</option> + {{ end }} + {{ end }} + </select> + <input type="submit" value="Download" /> + </form> + </td> </tr> {{ end }} </table> {{ if gt $categoryCount 0 }} -<div class="cat"> - <span>{{ range $category, $paper := .Papers.List }}<span class="nowrap">[<a href="#{{ $category }}">{{ $category }}</a>]</span> {{ end }}</span> +<div class="cat-cont"> + <div class="cat"> + {{ range $category, $paper := .Papers.List }} + <span class="cat">[<a href="#{{ $category }}">{{ $category }}</a>]</span> + {{ end }} + </div> </div> -<table class='tabs'> - <tr> - <td><a class='active' href='/admin/edit/'>Edit</a></td> - </tr> -</table> +<p class="Pp"><a class='active' href='/admin/edit/'>Edit</a></p> <div class='content'> {{ block "list" . }}{{ end }} </div> diff --git a/templates/index.html b/templates/index.html index d435a38..861410d 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,21 +1,22 @@ {{ template "layout.html" . }} {{ define "content" }} -<table id='header'> -</table> + +<div class="content"> {{ $categoryCount := len .Papers.List }} {{ if gt $categoryCount 0 }} -<div class="cat"> - <span>{{ range $category, $paper := .Papers.List }}<span class="nowrap">[<a href="#{{ $category }}">{{ $category }}</a>]</span> {{ end }}</span> +<div class="cat-cont"> + <div class="cat"> + {{ range $category, $paper := .Papers.List }} + <span class="cat">[<a href="#{{ $category }}">{{ $category }}</a>]</span> + {{ end }} + </div> </div> -<table class='tabs'> - <tr> - <td><a class='active' href='/admin/'>Manage</a></td> - </tr> -</table> -<div class="content"> +<p class="Pp"><a class='active' href='/admin/'>Manage</a></p> {{ block "list" . }}{{ end }} </div> {{ else }} -<p>nothing here yet, <a style="text-decoration:underline;" href="/admin/">create a category</a> to start downloading papers</p> +<p>nothing here yet, +<a style="text-decoration:underline;" href="/admin/">create a category</a> +to start downloading papers</p> {{ end }} {{ end }} diff --git a/templates/layout.html b/templates/layout.html index b9449b6..9f6109b 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -2,255 +2,49 @@ <html> <head> <meta charset="utf-8"/> -<meta name="viewport" content="width=device-width, initial-scale=1"> +<meta name="viewport" content="width=device-width, initial-scale=1"/> <title>Crane</title> <style> -@media (min-width: 601px) { - div#crane { - font-size: 16px; - } -} -@media (max-width: 600px) { - div#crane { - font-size: 14px; - } -} - -html, body { - background: #fbfaf9 -} - -div#crane { - font-family: 'Cousine', 'Courier', 'monospace'; - background: #fff; - padding: 1.5em; - max-width: 65em; - margin: auto; - overflow-wrap: break-word; - border: 1px solid #eee; - box-shadow: 0 0 .5em #999; - border-radius: 2px; -} - -div#crane ul { - list-style: square; - padding-left: 1.5em; - padding-right: .5em; -} - -div#crane a { - color: #000; - text-decoration: none; -} - -div#crane table#header input[type="text"] { - font-family: inherit; - font-size: 100%; - display: block; - width: calc(100% - 1rem); - border: 1px solid #888; - border-color: #888; - padding: .375rem; - background-color: #fff; - background-clip: padding-box; - margin-bottom: .5em; - line-height: 1.5; - transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out; -} - -div#crane .btn { - font-family: inherit; - font-size: 85%; - color: black; - text-overflow: unset; - display: inline; - background: #e9ecef; - border: #343a40 1px solid; - padding-right: 8px; - padding-top: 3px; - padding-bottom: 3px; - border-radius: 0; - display: inline-block; -} - -div#crane .sel { - font-family: inherit; - font-size: 85%; - color: black; - text-overflow: unset; - display: inline; - background: #e9ecef; - border: #343a40 1px solid; - padding: 2px 8px; - border-radius: 0; - display: inline-block; -} - -div#crane table { - border-collapse: collapse; -} - -div#crane table#header { - width: 100%; - margin-bottom: 0.5em; -} - -div#crane table#header td.inpt { - padding-left: 10px; - white-space: nowrap; - border-collapse: collapse; - color: #000; - padding-bottom: 1em; -} - -div#crane table#header td.main { - font-size: 250%; - padding-left: 10px; - white-space: nowrap; - border-collapse: collapse; -} - -div#crane table#header td.form { - text-align: left; - vertical-align: bottom; - padding-bottom: 2px; - white-space: nowrap; -} - -div#crane table#header td.sub { - color: #777; - border-top: solid 1px #ccc; - padding-left: 10px; -} - -div#crane table.tabs { - font-family: sans-serif; - font-size: 90%; - border-bottom: solid 2px #ccc; - border-collapse: nowrap; - margin-top: 1em; - margin-bottom: 0px; - width: 100%; -} - -div#crane table.tabs td { - padding: 0px 0px 0px; - vertical-align: bottom; -} - -div#crane table.tabs td a { - font-size: 90%; - padding: 2px 0.75em; - color: black; - background-color: #ccc; -} - -div#crane table.tabs td.form form { - padding-bottom: 2px; - white-space: normal; - padding-left: 1em; -} - -div#crane div.content { - margin-top: 1em; -} - -div#crane div.cat { - text-align: left; - padding-left: .5em; - padding-right: .5em; - color: #555; - padding-bottom: 0.5em; - overflow-wrap: normal; - line-height: 1.5em; -} - -div#crane div.cat a { - text-decoration: underline; -} - -div#crane div.list { - width: 100%; - border: none; - border-collapse: collapse; - text-align: left; -} - -div#crane div.content div.action { - padding-top: 1em; - padding-bottom: 1em; -} - -div#crane div.list span.authors { - font-size: 80%; - color: #900; -} - -div#crane div.list span.year { - font-size: 80%; - color: #090; -} - -div#crane div.list span.doi a { - font-size: 80%; -} - -div#crane div.list span.journal { - font-size: 80%; -} - -div#crane div.list span { - border: none; -} - -div#crane div.list span.title { - padding-top: 0.5em; -} - -div#crane div.list span.title a { - text-decoration: underline; -} - -div#crane div.list div.papersection { - font-weight: bold; - padding-top: 0.5em; - color: black; -} - -div#crane hr { - border: solid 1px #ccc; -} - -div#crane div.footer { - margin-top: 0.5em; - text-align: center; - font-size: 80%; -} - -div#crane div.footer a { - color: #ccc; - text-decoration: none; -} - -div#crane div.footer a:hover { - text-decoration: underline; -} - -div#crane div.cat .nowrap { - white-space: nowrap; -} +table.head, table.foot { width: 100%; } +td.head-rtitle, td.foot-os { text-align: right; } +td.head-vol { text-align: center; } +div.Pp { margin: 1ex 0ex; } +div.Nd, div.Bf, div.Op { display: inline; } +span.Pa, span.Ad { font-style: italic; } +span.Ms { font-weight: bold; } +dl.Bl-diag > dt { font-weight: bold; } +code.Nm, code.Fl, code.Cm, code.Ic, code.In, code.Fd, code.Fn, +code.Cd { font-weight: bold; font-family: inherit; } + +html { font-family: monospace; line-height: 1.25em; } +body { max-width: 80ch; margin: 1em auto; padding: 0 1ch; } +table { border-collapse: collapse; } +table.Nm code.Nm { padding-right: 1ch; } +table.foot { margin-top: 1em; } + +html { background-color: var(--ansi16); color: var(--ansi17); } +a { color: var(--ansi4); } +a:visited { color: var(--ansi5); } +a.permalink { color: var(--ansi3); text-decoration: none; } + +div.paper { padding-bottom: 1em; } +div.cat-cont { margin-left: 1em; margin-right: 1em; } +div.cat { justify-content: space-between; display: flex; flex-wrap: wrap; } +div.action { padding-bottom: 1em; margin-left: 1em; } +span.doi a { text-decoration: none; } +span.title a { text-decoration: underline; color: blue; } +table.head a { text-decoration: none; } +table.admin { margin-left: 1em; margin-right: 1em; margin-bottom: 1em; } </style> </head> <body> -<center> -<div id='crane'> -<table id='header'> - <tr><td class='main'><a href="/">Crane</a></td></tr> - <tr><td class='sub'>Research literature download and organization</td></tr> -</table> +<div class="manual-text"> +<h1 class="Sh" id="CRANE"><a class="permalink" href="/">CRANE</a></h1> +<p class="Pp">Crane is a research literature download and categorization +service. The source code can be downloaded +<a href="https://git.jordan.im/crane">here</a>.</p> {{ block "content" . }}{{ end }} -<div class='footer'><a href='https://git.jordan.im/crane'>crane</a></div> </div> -</center> +<a href='https://git.jordan.im/crane'>crane</a> </body> </html> diff --git a/templates/list.html b/templates/list.html index 52e7bb9..132bb6d 100644 --- a/templates/list.html +++ b/templates/list.html @@ -1,37 +1,66 @@ {{ define "list" }} -<div class='papers nowrap list'> +<div> {{ range $category, $papers := .Papers.List }} {{ $paperCount := len $papers }} {{ if ge $paperCount 1 }} - <div class="papersection"> - <span class='papersection' id='{{ $category }}'>{{ $category }}</span> - </div> + <h1 id="{{ $category }}"> + <a class="permalink" href="#{{ $category }}">{{ $category }}</a> + </h1> {{ range $path, $paper := $papers }} - <ul> - <li> + <div class="paper"> {{ if $paper.Meta.Title }} - <span class="title"><a href='/download/{{ $path }}' title='{{ $paper.Meta.Title }}'>{{ $paper.Meta.Title }}</a></span><br> + <span class="title"> + <a href='/download/{{ $path }}' title='{{ $paper.Meta.Title }}'>{{ $paper.Meta.Title }}</a> + </span> + <br /> {{ else }} - <span class="title"><a href='/download/{{ $path }}' title='{{ $paper.PaperName }}'>{{ $paper.PaperName }}</a></span><br> + <span class="title"> + <a href='/download/{{ $path }}' title='{{ $paper.PaperName }}'>{{ $paper.PaperName }}</a> + </span> + <br /> {{ end }} - {{ $contCount := len $paper.Meta.Contributors }}{{ if ge $contCount 1 }} - <span class="authors">{{ range $index, $contributor := $paper.Meta.Contributors }}{{if $index}}, {{end}}{{ $contributor.FirstName }} {{ $contributor.LastName }}{{end}}</span><br> + {{ $contCount := len $paper.Meta.Contributors }} + {{ if ge $contCount 1 }} + <span class="authors"> + {{- range $index, $contributor := $paper.Meta.Contributors -}} + {{- if $index }}, {{ end -}} + {{- $contributor.FirstName }} {{ $contributor.LastName -}} + {{- end -}} + </span> + <br /> {{ end }} {{ $hasVal := false }} - {{ if $paper.Meta.PubYear }}{{ $hasVal = true }}<span class="year">{{ $paper.Meta.PubYear }}</span>{{ end }} + {{ if $paper.Meta.PubYear }} + {{ $hasVal = true }} + <span class="year">{{ $paper.Meta.PubYear }}</span> + {{ end }} - {{ if $paper.Meta.DOI }}{{ if $hasVal }}- {{end}}<span class="doi"><a href="https://doi.org/{{ $paper.Meta.DOI }}">{{ $paper.Meta.DOI }}</a></span> + {{ if $paper.Meta.DOI }} + {{ if $hasVal }}- {{end}} + <span class="doi"> + <a href="https://doi.org/{{ $paper.Meta.DOI }}">{{ $paper.Meta.DOI }}</a> + </span> - {{ else if $paper.Meta.ArxivID }}{{ if $hasVal }}- {{ end }}<span class="doi"><a href="https://arxiv.org/abs/{{ $paper.Meta.ArxivID }}">{{ $paper.Meta.ArxivID }}</a></span> - {{ else if $paper.Meta.Resource }}{{ if $hasVal }}- {{ end }}<span class="doi"><a href="{{ $paper.Meta.Resource }}">{{ $paper.Meta.Resource }}</a></span>{{ end }} + {{ else if $paper.Meta.ArxivID }} + {{ if $hasVal }}- {{ end }} + <span class="doi"> + <a href="https://arxiv.org/abs/{{ $paper.Meta.ArxivID }}">{{ $paper.Meta.ArxivID }}</a> + </span> + {{ else if $paper.Meta.Resource }} + {{ if $hasVal }}- {{ end }} + <span class="doi"> + <a href="{{ $paper.Meta.Resource }}">{{ $paper.Meta.Resource }}</a> + </span> + {{ end }} - {{ if $paper.Meta.Journal }}{{ if $hasVal }}- {{ end }}<span class="journal">{{ $paper.Meta.Journal }}</span>{{ end }} - </li> - </ul> + {{ if $paper.Meta.Journal }} + {{ if $hasVal }}- {{ end }} + <span class="journal">{{ $paper.Meta.Journal }}</span> + {{ end }} + </div> {{ end }} - <hr> {{ end }} {{ end }} </div> @@ -99,51 +99,51 @@ func getMetaFromCitation(resp *http.Response) (*Meta, error) { } } switch name { - case "citation_title": - meta.Title = cont - case "citation_author": - var c Contributor - // Doe, Jain - if strings.Contains(cont, ",") { - v := strings.Split(cont, ", ") - c.FirstName = strings.Join(v[1:], " ") - c.LastName = v[0] + case "citation_title": + meta.Title = cont + case "citation_author": + var c Contributor + // Doe, Jain + if strings.Contains(cont, ",") { + v := strings.Split(cont, ", ") + c.FirstName = strings.Join(v[1:], " ") + c.LastName = v[0] // Jain Doe - } else { - v := strings.Split(cont, " ") - c.FirstName = strings.Join(v[:len(v)-1], " ") - c.LastName = strings.Join(v[len(v)-1:], " ") - } - c.Role = "author" - if len(meta.Contributors) > 0 { - c.Sequence = "additional" - } else { - c.Sequence = "first" - } - meta.Contributors = append(meta.Contributors, c) - case "citation_date", "citation_publication_date": - var formats = []string{"2006-01-02", "2006/01/02", "2006"} - for _, format := range formats { - t, err := time.Parse(format, cont) - if err == nil { - meta.PubMonth = t.Month().String() - meta.PubYear = strconv.Itoa(t.Year()) - break - } + } else { + v := strings.Split(cont, " ") + c.FirstName = strings.Join(v[:len(v)-1], " ") + c.LastName = strings.Join(v[len(v)-1:], " ") + } + c.Role = "author" + if len(meta.Contributors) > 0 { + c.Sequence = "additional" + } else { + c.Sequence = "first" + } + meta.Contributors = append(meta.Contributors, c) + case "citation_date", "citation_publication_date": + var formats = []string{"2006-01-02", "2006/01/02", "2006"} + for _, format := range formats { + t, err := time.Parse(format, cont) + if err == nil { + meta.PubMonth = t.Month().String() + meta.PubYear = strconv.Itoa(t.Year()) + break } - case "citation_journal_title", "og:site_name", "DC.Publisher": - meta.Journal = cont - case "citation_firstpage": - meta.FirstPage = cont - case "citation_lastpage": - meta.LastPage = cont - case "citation_doi": - meta.DOI = cont - case "citation_arxiv_id": - meta.ArxivID = cont - case "citation_pdf_url": - meta.Resource = cont } + case "citation_journal_title", "og:site_name", "DC.Publisher": + meta.Journal = cont + case "citation_firstpage": + meta.FirstPage = cont + case "citation_lastpage": + meta.LastPage = cont + case "citation_doi": + meta.DOI = cont + case "citation_arxiv_id": + meta.ArxivID = cont + case "citation_pdf_url": + meta.Resource = cont + } } for c := n.FirstChild; c != nil; c = c.NextSibling { f(c) |