+17
appview/pages/pages.go
+17
appview/pages/pages.go
···
17
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
18
"github.com/alecthomas/chroma/v2/lexers"
19
"github.com/alecthomas/chroma/v2/styles"
20
"github.com/sotangled/tangled/appview/auth"
21
"github.com/sotangled/tangled/appview/db"
22
"github.com/sotangled/tangled/types"
···
198
Active string
199
TagMap map[string][]string
200
types.RepoIndexResponse
201
}
202
203
func (p *Pages) RepoIndexPage(w io.Writer, params RepoIndexParams) error {
···
205
if params.IsEmpty {
206
return p.executeRepo("repo/empty", w, params)
207
}
208
return p.executeRepo("repo/index", w, params)
209
}
210
···
17
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
18
"github.com/alecthomas/chroma/v2/lexers"
19
"github.com/alecthomas/chroma/v2/styles"
20
+
"github.com/microcosm-cc/bluemonday"
21
"github.com/sotangled/tangled/appview/auth"
22
"github.com/sotangled/tangled/appview/db"
23
"github.com/sotangled/tangled/types"
···
199
Active string
200
TagMap map[string][]string
201
types.RepoIndexResponse
202
+
HTMLReadme template.HTML
203
+
Raw bool
204
}
205
206
func (p *Pages) RepoIndexPage(w io.Writer, params RepoIndexParams) error {
···
208
if params.IsEmpty {
209
return p.executeRepo("repo/empty", w, params)
210
}
211
+
212
+
if params.ReadmeFileName != "" {
213
+
var htmlString string
214
+
ext := filepath.Ext(params.ReadmeFileName)
215
+
switch ext {
216
+
case ".md", ".markdown", ".mdown", ".mkdn", ".mkd":
217
+
htmlString = renderMarkdown(params.Readme)
218
+
default:
219
+
htmlString = string(params.Readme)
220
+
params.Raw = true
221
+
}
222
+
params.HTMLReadme = template.HTML(bluemonday.NewPolicy().Sanitize(htmlString))
223
+
}
224
+
225
return p.executeRepo("repo/index", w, params)
226
}
227
+9
-5
appview/pages/templates/repo/index.html
+9
-5
appview/pages/templates/repo/index.html
···
114
{{ end }}
115
116
117
-
{{ define "commitLog" }}
118
<div id="commit-log" class="hidden md:block md:col-span-1">
119
{{ range .Commits }}
120
<div class="relative px-2 pb-8">
···
191
192
193
{{ define "repoAfter" }}
194
-
{{- if .Readme }}
195
-
<section class="mt-4 p-6 rounded bg-white w-full mx-auto overflow-auto prose">
196
-
<article class="readme">
197
-
{{- .Readme -}}
198
</article>
199
</section>
200
{{- end -}}
···
114
{{ end }}
115
116
117
+
{{ define "commitLog" }}
118
<div id="commit-log" class="hidden md:block md:col-span-1">
119
{{ range .Commits }}
120
<div class="relative px-2 pb-8">
···
191
192
193
{{ define "repoAfter" }}
194
+
{{- if .HTMLReadme }}
195
+
<section class="mt-4 p-6 rounded bg-white w-full mx-auto overflow-auto {{ if not .Raw }} prose {{ end }}">
196
+
<article class="{{ if .Raw }}whitespace-pre{{end}}">
197
+
{{ if .Raw }}
198
+
<pre>{{ .HTMLReadme }}</pre>
199
+
{{ else }}
200
+
{{ .HTMLReadme }}
201
+
{{ end }}
202
</article>
203
</section>
204
{{- end -}}
+1
-1
appview/pages/templates/repo/issues/new.html
+1
-1
appview/pages/templates/repo/issues/new.html
+14
-32
knotserver/routes.go
+14
-32
knotserver/routes.go
···
8
"encoding/json"
9
"errors"
10
"fmt"
11
-
"html/template"
12
"log"
13
"net/http"
14
"path/filepath"
···
21
gogit "github.com/go-git/go-git/v5"
22
"github.com/go-git/go-git/v5/plumbing"
23
"github.com/go-git/go-git/v5/plumbing/object"
24
-
"github.com/russross/blackfriday/v2"
25
"github.com/sotangled/tangled/knotserver/db"
26
"github.com/sotangled/tangled/knotserver/git"
27
"github.com/sotangled/tangled/types"
···
102
rtags = append(rtags, &tr)
103
}
104
105
-
var readmeContent template.HTML
106
for _, readme := range h.c.Repo.Readme {
107
-
ext := filepath.Ext(readme)
108
content, _ := gr.FileContent(readme)
109
if len(content) > 0 {
110
-
switch ext {
111
-
case ".md", ".mkd", ".markdown":
112
-
unsafe := blackfriday.Run(
113
-
[]byte(content),
114
-
blackfriday.WithExtensions(blackfriday.CommonExtensions),
115
-
)
116
-
html := sanitize(unsafe)
117
-
readmeContent = template.HTML(html)
118
-
default:
119
-
safe := sanitize([]byte(content))
120
-
readmeContent = template.HTML(
121
-
fmt.Sprintf(`<pre>%s</pre>`, safe),
122
-
)
123
-
}
124
-
break
125
}
126
}
127
128
-
if readmeContent == "" {
129
-
l.Warn("no readme found")
130
-
}
131
-
132
files, err := gr.FileTree("")
133
if err != nil {
134
writeError(w, err.Error(), http.StatusInternalServerError)
···
147
}
148
149
resp := types.RepoIndexResponse{
150
-
IsEmpty: false,
151
-
Ref: ref,
152
-
Commits: commits,
153
-
Description: getDescription(path),
154
-
Readme: readmeContent,
155
-
Files: files,
156
-
Branches: bs,
157
-
Tags: rtags,
158
-
TotalCommits: total,
159
}
160
161
writeJSON(w, resp)
···
8
"encoding/json"
9
"errors"
10
"fmt"
11
"log"
12
"net/http"
13
"path/filepath"
···
20
gogit "github.com/go-git/go-git/v5"
21
"github.com/go-git/go-git/v5/plumbing"
22
"github.com/go-git/go-git/v5/plumbing/object"
23
"github.com/sotangled/tangled/knotserver/db"
24
"github.com/sotangled/tangled/knotserver/git"
25
"github.com/sotangled/tangled/types"
···
100
rtags = append(rtags, &tr)
101
}
102
103
+
var readmeContent string
104
+
var readmeFile string
105
for _, readme := range h.c.Repo.Readme {
106
content, _ := gr.FileContent(readme)
107
if len(content) > 0 {
108
+
readmeContent = string(content)
109
+
readmeFile = readme
110
}
111
}
112
113
files, err := gr.FileTree("")
114
if err != nil {
115
writeError(w, err.Error(), http.StatusInternalServerError)
···
128
}
129
130
resp := types.RepoIndexResponse{
131
+
IsEmpty: false,
132
+
Ref: ref,
133
+
Commits: commits,
134
+
Description: getDescription(path),
135
+
Readme: readmeContent,
136
+
ReadmeFileName: readmeFile,
137
+
Files: files,
138
+
Branches: bs,
139
+
Tags: rtags,
140
+
TotalCommits: total,
141
}
142
143
writeJSON(w, resp)
+10
-11
types/repo.go
+10
-11
types/repo.go
···
1
package types
2
3
import (
4
-
"html/template"
5
-
6
"github.com/go-git/go-git/v5/plumbing/object"
7
)
8
9
type RepoIndexResponse struct {
10
-
IsEmpty bool `json:"is_empty"`
11
-
Ref string `json:"ref,omitempty"`
12
-
Readme template.HTML `json:"readme,omitempty"`
13
-
Commits []*object.Commit `json:"commits,omitempty"`
14
-
Description string `json:"description,omitempty"`
15
-
Files []NiceTree `json:"files,omitempty"`
16
-
Branches []Branch `json:"branches,omitempty"`
17
-
Tags []*TagReference `json:"tags,omitempty"`
18
-
TotalCommits int `json:"total_commits,omitempty"`
19
}
20
21
type RepoLogResponse struct {
···
1
package types
2
3
import (
4
"github.com/go-git/go-git/v5/plumbing/object"
5
)
6
7
type RepoIndexResponse struct {
8
+
IsEmpty bool `json:"is_empty"`
9
+
Ref string `json:"ref,omitempty"`
10
+
Readme string `json:"readme,omitempty"`
11
+
ReadmeFileName string `json:"readme_file_name,omitempty"`
12
+
Commits []*object.Commit `json:"commits,omitempty"`
13
+
Description string `json:"description,omitempty"`
14
+
Files []NiceTree `json:"files,omitempty"`
15
+
Branches []Branch `json:"branches,omitempty"`
16
+
Tags []*TagReference `json:"tags,omitempty"`
17
+
TotalCommits int `json:"total_commits,omitempty"`
18
}
19
20
type RepoLogResponse struct {