Documentation
¶
Index ¶
- Variables
- func AppendBuiltins(b *gad.Builtins) *gad.Builtins
- func Compile(st *gad.SymbolTable, input []byte, opts gad.CompileOptions) (*giomnode.File, *gad.Bytecode, error)
- func CompileFallback(c *gad.Compiler, nd ast.Node) error
- func CompileFile(st *gad.SymbolTable, module *gad.ModuleSpec, file *giomnode.File, ...) (*gad.Bytecode, error)
- func Transpile(name string, src []byte, outPath string) error
- type FileImporter
- type Render
Constants ¶
This section is empty.
Variables ¶
var ( BuiltinEscape = &gad.Function{ FuncName: "giom$escape", Value: func(call gad.Call) (_ gad.Object, err error) { if err = call.Args.CheckLen(1); err != nil { return } var ( value = call.Args.GetOnly(0) s string ) switch t := value.(type) { case gad.RawStr: s = string(t) case gad.Str: s = string(t) default: var v gad.Object if v, err = call.VM.Builtins.Call(gad.BuiltinStr, call); err != nil { return } s = string(v.(gad.Str)) } return gad.RawStr(s), nil }, } AttrFunc = func(vm *gad.VM, name, value gad.Object) (ret gad.RawStr, err error) { var ( toRawStr = vm.Builtins.ArgsInvoker(gad.BuiltinRawStr, gad.Call{VM: vm}) ) if value.IsFalsy() { return } if _, ok := name.(gad.RawStr); !ok { if name, err = toRawStr(name); err != nil { return } } switch t := value.(type) { case gad.Array: var b strings.Builder for _, o := range t { if o.IsFalsy() { continue } if _, ok := o.(gad.RawStr); !ok { if o, err = toRawStr(o); err != nil { return } } b.WriteString(string(o.(gad.RawStr))) b.WriteString(" ") } value = gad.RawStr(strings.TrimSpace(b.String())) case gad.RawStr: case gad.Flag: if t { return gad.RawStr(name.ToString()), nil } return "", nil default: if value, err = toRawStr(value); err != nil { return } } return gad.RawStr(name.ToString() + "=" + strconv.Quote(value.ToString())), nil } BuiltinAttr = &gad.Function{ FuncName: "giom$attr", Value: func(call gad.Call) (ret gad.Object, err error) { if err = call.Args.CheckLen(2); err != nil { return } ret, err = AttrFunc(call.VM, call.Args.GetOnly(0), call.Args.GetOnly(1)) return }, } BuiltinAttrs = &gad.Function{ FuncName: "giom$attrs", Value: func(call gad.Call) (_ gad.Object, err error) { var ( b strings.Builder rs gad.RawStr keys []string d = make(gad.Dict) class []string style []string filter func(arr gad.Array) (ret gad.Array) ) filter = func(arr gad.Array) (ret gad.Array) { for _, v := range arr { switch t := v.(type) { case *gad.KeyValue: if !t.K.IsFalsy() { ret = append(ret, t.V) } case gad.Array: ret = append(ret, filter(t)...) default: if !t.IsFalsy() { ret = append(ret, t) } } } return } cb := func(na *gad.KeyValue) (err error) { var k string switch t := na.K.(type) { case gad.Bool: case gad.Str: k = string(t) case gad.RawStr: k = string(t) default: var s gad.Str if s, err = gad.ToStr(call.VM, t); err != nil { return } k = string(s) } switch k { case "class": if !na.V.IsFalsy() { switch t := na.V.(type) { case gad.Str: if len(t) > 0 { class = append(class, string(t)) } case gad.RawStr: if len(t) > 0 { class = append(class, string(t)) } case *gad.KeyValue: if !t.K.IsFalsy() { var arr gad.Array switch t := t.V.(type) { case gad.Array: arr = t default: arr = gad.Array{t} } for _, o := range filter(arr) { var s gad.Str if s, err = gad.ToStr(call.VM, o); err != nil { return } class = append(class, string(s)) } } case gad.Array: for _, o := range filter(t) { var s gad.Str if s, err = gad.ToStr(call.VM, o); err != nil { return } class = append(class, string(s)) } } } case "style": switch t := na.V.(type) { case gad.Str: if len(t) > 0 { style = append(style, string(t)) } case gad.RawStr: if len(t) > 0 { style = append(style, string(t)) } case *gad.KeyValue: if !t.K.IsFalsy() { var arr gad.Array switch t := t.V.(type) { case gad.Array: arr = t default: arr = gad.Array{t} } for _, o := range filter(arr) { var s gad.Str if s, err = gad.ToStr(call.VM, o); err != nil { return } style = append(style, string(s)) } } case gad.Array: for _, o := range filter(t) { var s gad.Str if s, err = gad.ToStr(call.VM, o); err != nil { return } style = append(style, string(s)) } case gad.Dict: for key, o := range t { var s gad.Str if s, err = gad.ToStr(call.VM, o); err != nil { return } style = append(style, key+":"+string(s)) } } default: v := na.V switch t := v.(type) { case *gad.KeyValue: if t.K.IsFalsy() { return } v = t.V } if _, ok := d[k]; !ok { keys = append(keys, k) } d[k] = v } return err } err = call.NamedArgs.Walk(func(na *gad.KeyValue) (err error) { var v gad.Object = na switch t := na.K.(type) { case gad.Bool: if !t { return } v = na.V } switch t := v.(type) { case gad.Array: return gad.ItemsOfCb(call.VM, &gad.NamedArgs{}, cb, na.V) case *gad.KeyValue: return cb(t) case gad.KeyValueArray: for _, value := range t { if err = cb(value); err != nil { return } } return default: return cb(na) } }) if err != nil { return } for _, key := range keys { if rs, err = AttrFunc(call.VM, gad.Str(key), d[key]); err == nil && rs != "" { b.WriteString(" " + string(rs)) } } if len(class) > 0 { b.WriteString(" class=") b.WriteString(strconv.Quote(strings.Join(class, " "))) } if len(style) > 0 { b.WriteString(" style=") b.WriteString(strconv.Quote(strings.Join(style, "; "))) } return gad.RawStr(b.String()), nil }, } BuiltinTextWrite = &gad.Function{ FuncName: "giom$write", Value: func(call gad.Call) (_ gad.Object, err error) { return call.VM.Builtins.Call(gad.BuiltinWrite, call) }, } )
Functions ¶
func AppendBuiltins ¶
AppendBuiltins registers giom built-in functions (escape, attr, attrs, write) into the given Builtins and returns it.
func Compile ¶
func Compile(st *gad.SymbolTable, input []byte, opts gad.CompileOptions) (*giomnode.File, *gad.Bytecode, error)
Compile parses giom v2 source and compiles it to GAD bytecode.
func CompileFallback ¶
CompileFallback compiles Giom-specific AST nodes through a Gad compiler.
func CompileFile ¶
func CompileFile(st *gad.SymbolTable, module *gad.ModuleSpec, file *giomnode.File, opts gad.CompileOptions) (*gad.Bytecode, error)
CompileFile compiles a parsed giom v2 file to GAD bytecode.
Types ¶
type FileImporter ¶
type FileImporter struct {
NameResolver func(cwd, name string) (string, error)
WorkDir string
FileReader func(string) (data []byte, uri string, err error)
TranspilePath func(srcPath string) string
// contains filtered or unexported fields
}
FileImporter imports Gad and Giom files from the filesystem.
Files ending in .giom are returned as gad.BuiltinCompileModuleFunc so they are parsed and compiled with Giom syntax during Gad import compilation.
func (*FileImporter) Fork ¶
func (m *FileImporter) Fork(moduleName string) gad.ExtImporter
Fork returns an importer rooted at the imported module's directory.
func (*FileImporter) Get ¶
func (m *FileImporter) Get(name string) gad.ExtImporter
Get returns this importer for a non-empty module name.
func (*FileImporter) Import ¶
func (m *FileImporter) Import(ctx context.Context, module *gad.ModuleSpec) (data any, uri string, err error)
Import reads the resolved module. Giom modules are compiled through a builtin module compiler function; other files are returned as source bytes.
func (*FileImporter) Name ¶
func (m *FileImporter) Name() (string, error)
Name resolves the current import name into the compiler module cache key.
type Render ¶
type Render struct {
// TemplateDelay is the debounce duration before recompiling after
// a file change is detected. Defaults to 15s.
TemplateDelay time.Duration
// TranspilePath returns the output path for transpiled .gad files.
// If nil, transpilation is skipped.
TranspilePath func(srcPath string) string
// BuiltinsFunc returns the Gad builtins to use for compilation.
// If nil, defaults to AppendBuiltins(gad.NewBuiltins()).
BuiltinsFunc func() *gad.Builtins
ModuleMapFunc func(mm *gad.ModuleMap) *gad.ModuleMap
// contains filtered or unexported fields
}
Render handles Giom template rendering with bytecode caching and automatic recompilation on file changes. It is safe for concurrent use.
func NewRender ¶
NewRender creates a Render with the given workDir. Non-empty paths are resolved to an absolute path. Other fields (TemplateDelay, TranspilePath, BuiltinsFunc) may be set on the returned value before use.
func (*Render) OnRender ¶
func (r *Render) OnRender(f ...func(first bool, mainFile string, files []string, lastTime time.Time, err error)) *Render
OnRender appends callback functions invoked after compilation. On first render, first=true with empty files and zero lastTime. On recompilation due to file changes, first=false with the changed file paths. If compilation fails, err is non-nil and the cached entry is not updated. Returns the Render for chaining.