add simple xlsx file render support

This commit is contained in:
Lunny Xiao 2018-06-03 13:38:38 +08:00
parent fb1daad13d
commit 5cebd55a82
No known key found for this signature in database
GPG Key ID: C3B7C91B632F738A
4 changed files with 111 additions and 24 deletions

View File

@ -16,6 +16,7 @@ import (
// register supported doc types
_ "code.gitea.io/gitea/modules/markup/markdown"
_ "code.gitea.io/gitea/modules/markup/orgmode"
_ "code.gitea.io/gitea/modules/markup/xlsx"
"github.com/urfave/cli"
)

View File

@ -32,6 +32,8 @@ func NewSanitizer() {
// We only want to allow HighlightJS specific classes for code blocks
sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^language-\w+$`)).OnElements("code")
sanitizer.policy.AllowAttrs("class", "data-tab").OnElements("div", "a")
// Checkboxes
sanitizer.policy.AllowAttrs("type").Matching(regexp.MustCompile(`^checkbox$`)).OnElements("input")
sanitizer.policy.AllowAttrs("checked", "disabled").OnElements("input")

View File

@ -0,0 +1,84 @@
// Copyright 20178 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package xlsx
import (
"bytes"
"fmt"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"github.com/360EntSecGroup-Skylar/excelize"
)
func init() {
markup.RegisterParser(Parser{})
}
// Parser implements markup.Parser for orgmode
type Parser struct {
}
// Name implements markup.Parser
func (Parser) Name() string {
return "Excel(.xlsx)"
}
// Extensions implements markup.Parser
func (Parser) Extensions() []string {
return []string{".xlsx"}
}
// Render implements markup.Parser
func (Parser) Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
rd, err := excelize.OpenReader(bytes.NewReader(rawBytes))
if err != nil {
return []byte{}
}
var sheetMap = rd.GetSheetMap()
if len(sheetMap) == 0 {
return []byte{}
}
var tmpBlock bytes.Buffer
tmpBlock.WriteString(`<div class="ui top attached tabular menu">`)
for i := 0; i < len(sheetMap); i++ {
var active string
if i == 0 {
active = "active"
}
tmpBlock.WriteString(fmt.Sprintf(`<a class="%s item" data-tab="%d">%s</a>`, active, i, sheetMap[i+1]))
}
tmpBlock.WriteString(`</div>`)
for i := 0; i < len(sheetMap); i++ {
var active string
if i == 0 {
active = "active"
}
tmpBlock.WriteString(fmt.Sprintf(`<div data-tab="%d" class="ui bottom attached `+
active+` tab segment"><table class="table">`, i))
rows, err := rd.Rows(sheetMap[i+1])
if err != nil {
log.Error(1, "Rows: %v", err)
tmpBlock.WriteString("</table></div>")
continue
}
for rows.Next() {
fields := rows.Columns()
tmpBlock.WriteString("<tr>")
for _, field := range fields {
tmpBlock.WriteString("<td>")
tmpBlock.WriteString(field)
tmpBlock.WriteString("</td>")
}
tmpBlock.WriteString("<tr>")
}
tmpBlock.WriteString("</table></div>")
}
return tmpBlock.Bytes()
}

View File

@ -91,24 +91,24 @@ func renderDirectory(ctx *context.Context, treeLink string) {
ctx.Data["FileIsText"] = isTextFile
ctx.Data["FileName"] = readmeFile.Name()
// FIXME: what happens when README file is an image?
if isTextFile {
if readmeFile.Size() >= setting.UI.MaxDisplayFileSize {
// Pretend that this is a normal text file to display 'This file is too large to be shown'
ctx.Data["IsFileTooLarge"] = true
ctx.Data["IsTextFile"] = true
ctx.Data["FileSize"] = readmeFile.Size()
//if isTextFile {
if readmeFile.Size() >= setting.UI.MaxDisplayFileSize {
// Pretend that this is a normal text file to display 'This file is too large to be shown'
ctx.Data["IsFileTooLarge"] = true
ctx.Data["IsTextFile"] = true
ctx.Data["FileSize"] = readmeFile.Size()
} else {
d, _ := ioutil.ReadAll(dataRc)
buf = append(buf, d...)
if markup.Type(readmeFile.Name()) != "" {
ctx.Data["IsMarkup"] = true
ctx.Data["FileContent"] = string(markup.Render(readmeFile.Name(), buf, treeLink, ctx.Repo.Repository.ComposeMetas()))
} else {
d, _ := ioutil.ReadAll(dataRc)
buf = append(buf, d...)
if markup.Type(readmeFile.Name()) != "" {
ctx.Data["IsMarkup"] = true
ctx.Data["FileContent"] = string(markup.Render(readmeFile.Name(), buf, treeLink, ctx.Repo.Repository.ComposeMetas()))
} else {
ctx.Data["IsRenderedHTML"] = true
ctx.Data["FileContent"] = string(bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1))
}
ctx.Data["IsRenderedHTML"] = true
ctx.Data["FileContent"] = string(bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1))
}
}
//}
}
// Show latest commit info of repository in table header,
@ -192,7 +192,14 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
}
switch {
case isTextFile:
case base.IsPDFFile(buf):
ctx.Data["IsPDFFile"] = true
case base.IsVideoFile(buf):
ctx.Data["IsVideoFile"] = true
case base.IsImageFile(buf):
ctx.Data["IsImageFile"] = true
default:
//case isTextFile:
if blob.Size() >= setting.UI.MaxDisplayFileSize {
ctx.Data["IsFileTooLarge"] = true
break
@ -209,7 +216,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
} else if readmeExist {
ctx.Data["IsRenderedHTML"] = true
ctx.Data["FileContent"] = string(bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1))
} else {
} else if isTextFile {
// Building code view blocks with line number on server side.
var fileContent string
if content, err := templates.ToUTF8WithErr(buf); err != nil {
@ -251,13 +258,6 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
} else if !ctx.Repo.IsWriter() {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.fork_before_edit")
}
case base.IsPDFFile(buf):
ctx.Data["IsPDFFile"] = true
case base.IsVideoFile(buf):
ctx.Data["IsVideoFile"] = true
case base.IsImageFile(buf):
ctx.Data["IsImageFile"] = true
}
if ctx.Repo.CanEnableEditor() {