1
0
treerack/cmd/treerack/show.go

110 lines
2.2 KiB
Go
Raw Normal View History

2018-01-08 21:03:00 +01:00
package main
2018-01-09 00:21:35 +01:00
import (
2025-08-19 00:56:08 +02:00
"code.squareroundforest.org/arpio/treerack"
2025-08-20 00:45:32 +02:00
"encoding/json"
2026-01-15 23:33:40 +01:00
"io"
2018-01-09 00:21:35 +01:00
)
2018-01-10 00:44:14 +01:00
type showOptions struct {
2026-01-15 23:33:40 +01:00
// Syntax specifies the filename of the syntax definition file.
Syntax string
// SyntaxString specifies the syntax as an inline string.
SyntaxString string
// Input specifies the filename of the input content to be validated.
Input string
// InputString specifies the input content as an inline string.
InputString string
// Pretty enables indented, human-readable output.
Pretty bool
// Indent specifies a custom indentation string for the output.
Indent string
2018-01-09 00:21:35 +01:00
}
type node struct {
2026-01-15 23:33:40 +01:00
Name string `json:"name"`
From int `json:"from"`
To int `json:"to"`
Text string `json:"text,omitempty"`
Nodes []node `json:"nodes,omitempty"`
2018-01-09 00:21:35 +01:00
}
2026-01-15 23:33:40 +01:00
func mapNode(n *treerack.Node) node {
2018-01-09 00:21:35 +01:00
var nn node
nn.Name = n.Name
nn.From = n.From
nn.To = n.To
if len(n.Nodes) == 0 {
nn.Text = n.Text()
2026-01-15 23:33:40 +01:00
return nn
2018-01-09 00:21:35 +01:00
}
for i := range n.Nodes {
nn.Nodes = append(nn.Nodes, mapNode(n.Nodes[i]))
}
2026-01-15 23:33:40 +01:00
return nn
2018-01-09 00:21:35 +01:00
}
2026-01-15 23:33:40 +01:00
// show input content against a provided syntax definition and outputs the resulting AST (Abstract Syntax Tree)
// in JSON format. Syntax can be provided via a filename option or an inline string option. Input can be
// provided via a filename option, a positional argument filename, an inline string option, or piped from
// standard input.
func show(o showOptions, stdin io.Reader, stdout io.Writer, args ...string) error {
syntax, finalizeSyntax, err := initInput(o.Syntax, o.SyntaxString, nil, nil)
if err != nil {
return err
2018-01-09 00:21:35 +01:00
}
2026-01-15 23:33:40 +01:00
defer finalizeSyntax()
input, finalizeInput, err := initInput(o.Input, o.InputString, stdin, args)
if err != nil {
return err
2018-01-09 00:21:35 +01:00
}
2026-01-15 23:33:40 +01:00
defer finalizeInput()
s := &treerack.Syntax{}
if err := s.ReadSyntax(syntax); err != nil {
return err
2018-01-09 00:21:35 +01:00
}
2026-01-15 23:33:40 +01:00
if err := s.Init(); err != nil {
return err
2018-01-09 00:21:35 +01:00
}
n, err := s.Parse(input)
if err != nil {
2026-01-15 23:33:40 +01:00
return err
2018-01-09 00:21:35 +01:00
}
nn := mapNode(n)
2026-01-15 23:33:40 +01:00
encode := json.Marshal
if o.Pretty || o.Indent != "" {
if o.Indent == "" {
o.Indent = " "
2018-01-09 00:21:35 +01:00
}
2026-01-15 23:33:40 +01:00
encode = func(a any) ([]byte, error) {
return json.MarshalIndent(a, "", o.Indent)
2018-01-09 00:21:35 +01:00
}
}
2026-01-15 23:33:40 +01:00
b, err := encode(nn)
2018-01-09 00:21:35 +01:00
if err != nil {
2026-01-15 23:33:40 +01:00
return err
}
if _, err := stdout.Write(b); err != nil {
return err
2018-01-09 00:21:35 +01:00
}
2026-01-15 23:33:40 +01:00
return nil
2018-01-08 21:03:00 +01:00
}