forked from golang/gddo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
present.go
74 lines (68 loc) · 1.71 KB
/
present.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.
package gosrc
import (
"path/filepath"
"regexp"
"time"
)
type Presentation struct {
Filename string
Files map[string][]byte
Updated time.Time
}
type presBuilder struct {
filename string
data []byte
resolveURL func(fname string) string
fetch func(fnames []string) ([]*File, error)
}
var assetPat = regexp.MustCompile(`(?m)^\.(play|code|image|iframe|html)\s+(?:-\S+\s+)*(\S+)`)
func (b *presBuilder) build() (*Presentation, error) {
var data []byte
var fnames []string
i := 0
for _, m := range assetPat.FindAllSubmatchIndex(b.data, -1) {
name := filepath.Clean(string(b.data[m[4]:m[5]]))
switch string(b.data[m[2]:m[3]]) {
case "iframe", "image":
data = append(data, b.data[i:m[4]]...)
data = append(data, b.resolveURL(name)...)
case "html":
// TODO: sanitize and fix relative URLs in HTML.
data = append(data, "\nERROR: .html not supported\n"...)
case "play", "code":
data = append(data, b.data[i:m[5]]...)
found := false
for _, n := range fnames {
if n == name {
found = true
break
}
}
if !found {
fnames = append(fnames, name)
}
default:
data = append(data, "\nERROR: unknown command\n"...)
}
i = m[5]
}
data = append(data, b.data[i:]...)
files, err := b.fetch(fnames)
if err != nil {
return nil, err
}
pres := &Presentation{
Updated: time.Now().UTC(),
Filename: b.filename,
Files: map[string][]byte{b.filename: data},
}
for _, f := range files {
pres.Files[f.Name] = f.Data
}
return pres, nil
}