OSDN Git Service

libgo: Update to weekly 2011-11-09.
[pf3gnuchains/gcc-fork.git] / libgo / go / text / template / set.go
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package template
6
7 import (
8         "fmt"
9         "io"
10         "reflect"
11         "text/template/parse"
12 )
13
14 // Set holds a set of related templates that can refer to one another by name.
15 // The zero value represents an empty set.
16 // A template may be a member of multiple sets.
17 type Set struct {
18         tmpl       map[string]*Template
19         leftDelim  string
20         rightDelim string
21         parseFuncs FuncMap
22         execFuncs  map[string]reflect.Value
23 }
24
25 func (s *Set) init() {
26         if s.tmpl == nil {
27                 s.tmpl = make(map[string]*Template)
28                 s.parseFuncs = make(FuncMap)
29                 s.execFuncs = make(map[string]reflect.Value)
30         }
31 }
32
33 // Delims sets the action delimiters, to be used in a subsequent
34 // parse, to the specified strings.
35 // An empty delimiter stands for the corresponding default: {{ or }}.
36 // The return value is the set, so calls can be chained.
37 func (s *Set) Delims(left, right string) *Set {
38         s.leftDelim = left
39         s.rightDelim = right
40         return s
41 }
42
43 // Funcs adds the elements of the argument map to the set's function map.  It
44 // panics if a value in the map is not a function with appropriate return
45 // type.
46 // The return value is the set, so calls can be chained.
47 func (s *Set) Funcs(funcMap FuncMap) *Set {
48         s.init()
49         addValueFuncs(s.execFuncs, funcMap)
50         addFuncs(s.parseFuncs, funcMap)
51         return s
52 }
53
54 // Add adds the argument templates to the set. It panics if two templates
55 // with the same name are added or if a template is already a member of
56 // a set.
57 // The return value is the set, so calls can be chained.
58 func (s *Set) Add(templates ...*Template) *Set {
59         for _, t := range templates {
60                 if err := s.add(t); err != nil {
61                         panic(err)
62                 }
63         }
64         return s
65 }
66
67 // add adds the argument template to the set.
68 func (s *Set) add(t *Template) error {
69         s.init()
70         if t.set != nil {
71                 return fmt.Errorf("template: %q already in a set", t.name)
72         }
73         if _, ok := s.tmpl[t.name]; ok {
74                 return fmt.Errorf("template: %q already defined in set", t.name)
75         }
76         s.tmpl[t.name] = t
77         t.set = s
78         return nil
79 }
80
81 // Template returns the template with the given name in the set,
82 // or nil if there is no such template.
83 func (s *Set) Template(name string) *Template {
84         return s.tmpl[name]
85 }
86
87 // FuncMap returns the set's function map.
88 func (s *Set) FuncMap() FuncMap {
89         return s.parseFuncs
90 }
91
92 // Execute applies the named template to the specified data object, writing
93 // the output to wr.
94 func (s *Set) Execute(wr io.Writer, name string, data interface{}) error {
95         tmpl := s.tmpl[name]
96         if tmpl == nil {
97                 return fmt.Errorf("template: no template %q in set", name)
98         }
99         return tmpl.Execute(wr, data)
100 }
101
102 // Parse parses a string into a set of named templates.  Parse may be called
103 // multiple times for a given set, adding the templates defined in the string
104 // to the set.  It is an error if a template has a name already defined in the set.
105 func (s *Set) Parse(text string) (*Set, error) {
106         trees, err := parse.Set(text, s.leftDelim, s.rightDelim, s.parseFuncs, builtins)
107         if err != nil {
108                 return nil, err
109         }
110         s.init()
111         for name, tree := range trees {
112                 tmpl := New(name)
113                 tmpl.Tree = tree
114                 err = s.add(tmpl)
115                 if err != nil {
116                         return s, err
117                 }
118         }
119         return s, nil
120 }