Repository navigation
Expand file tree
/
Copy pathexamples.go
More file actions
69 lines (59 loc) · 1.98 KB
/
Copy pathexamples.go
File metadata and controls
69 lines (59 loc) · 1.98 KB
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
package main
import (
"embed"
"io"
"io/fs"
"os"
"path/filepath"
"github.com/some-programs/present/pkg/present"
)
// examplesFS holds the example presentations, which -doc serves at
// examplesPath.
//
//go:embed all:examples
var examplesFS embed.FS
// examplesPath is the URL path that the examples are served at.
const examplesPath = "/_examples"
// examplesRoot is the root that the examples are served from with -doc.
// Their diagrams are not rendered, so they come with their SVG files.
var examplesRoot = contentRoot{prefix: examplesPath, fsys: must(fs.Sub(examplesFS, "examples"))}
func must[T any](v T, err error) T {
if err != nil {
panic(err)
}
return v
}
// A contentRoot is a tree of files that presentations are served from.
// The files are named by slash-separated paths in fsys, as fs.FS has it.
type contentRoot struct {
prefix string // the URL path the files are served at, "" for the root
fsys fs.FS
// dir is the directory that fsys reads, which diagrams are rendered
// to, or "" if fsys is read-only, as the embedded examples are.
dir string
}
// dirRoot returns the root of the files in the directory dir.
func dirRoot(dir string) contentRoot {
if r, err := os.OpenRoot(dir); err == nil {
return contentRoot{fsys: r.FS(), dir: dir}
}
return contentRoot{fsys: os.DirFS(dir), dir: dir}
}
// parse parses the presentation read from r, the file name in fsys, with
// the files it includes read from fsys.
func parse(fsys fs.FS, r io.Reader, name string, mode present.ParseMode) (*present.Doc, error) {
ctx := present.Context{ReadFile: func(name string) ([]byte, error) {
// The present package joins names with filepath.
return fs.ReadFile(fsys, filepath.ToSlash(name))
}}
return ctx.Parse(r, name, mode)
}
// parseFile parses the presentation file name in fsys.
func parseFile(fsys fs.FS, name string, mode present.ParseMode) (*present.Doc, error) {
f, err := fsys.Open(name)
if err != nil {
return nil, err
}
defer f.Close()
return parse(fsys, f, name, mode)
}