add simple xlsx file render support
This commit is contained in:
parent
fb1daad13d
commit
5cebd55a82
1
main.go
1
main.go
|
|
@ -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"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
84
modules/markup/xlsx/xlsx.go
Normal file
84
modules/markup/xlsx/xlsx.go
Normal 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()
|
||||
}
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user