Skip to content

Commit

Permalink
Handle lists with references for names
Browse files Browse the repository at this point in the history
  • Loading branch information
hasty committed Sep 11, 2024
1 parent 8a047de commit 1ada52f
Show file tree
Hide file tree
Showing 6 changed files with 315 additions and 150 deletions.
171 changes: 73 additions & 98 deletions matter/spec/commands.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package spec

import (
"fmt"
"iter"
"log/slog"
"regexp"
"strings"
Expand All @@ -16,138 +16,113 @@ import (

var parentheticalExpressionPattern = regexp.MustCompile(`\s*\([^\)]+\)$`)

func (s *Section) toCommands(d *Doc, entityMap map[asciidoc.Attributable][]types.Entity) (commands matter.CommandSet, err error) {

t := FindFirstTable(s)
if t == nil {

return
}
type commandFactory struct{}

var commandMap map[string]*matter.Command
commands, commandMap, err = s.buildCommands(d, t)
func (cf *commandFactory) New(d *Doc, s *Section, row *asciidoc.TableRow, columnMap ColumnIndex, name string) (*matter.Command, error) {
cmd := matter.NewCommand(s.Base)
var err error
cmd.ID, err = readRowID(row, columnMap, matter.TableColumnID)
if err != nil {
err = fmt.Errorf("error reading commands table: %w", err)
return
return nil, err
}

for _, s := range parse.Skim[*Section](s.Elements()) {
switch s.SecType {
case matter.SectionCommand:
var c *matter.Command
c, err = s.toCommand(d, commandMap, entityMap)
if err != nil {
return
}
if c != nil {
entityMap[s.Base] = append(entityMap[s.Base], c)
}
}
cmd.Name = text.TrimCaseInsensitiveSuffix(name, " Command")
var dir string
dir, err = readRowASCIIDocString(row, columnMap, matter.TableColumnDirection)
if err != nil {
return nil, err
}
return
}

func (s *Section) buildCommands(d *Doc, t *asciidoc.Table) (commands matter.CommandSet, commandMap map[string]*matter.Command, err error) {
var rows []*asciidoc.TableRow
var headerRowIndex int
var columnMap ColumnIndex
rows, headerRowIndex, columnMap, _, err = parseTable(d, s, t)
cmd.Direction = ParseCommandDirection(dir)
cmd.Response, err = readRowASCIIDocString(row, columnMap, matter.TableColumnResponse)
if err != nil {
return
return nil, err
}
commandMap = make(map[string]*matter.Command)
for i := headerRowIndex + 1; i < len(rows); i++ {
row := rows[i]
cmd := matter.NewCommand(s.Base)
cmd.ID, err = readRowID(row, columnMap, matter.TableColumnID)
if err != nil {
return
}
cmd.Name, err = ReadRowValue(d, row, columnMap, matter.TableColumnName)
if err != nil {
return
}
cmd.Name = text.TrimCaseInsensitiveSuffix(cmd.Name, " Command")
var dir string
dir, err = readRowASCIIDocString(row, columnMap, matter.TableColumnDirection)
if err != nil {
return
}
cmd.Direction = ParseCommandDirection(dir)
cmd.Response, err = readRowASCIIDocString(row, columnMap, matter.TableColumnResponse)
if err != nil {
return
}
cmd.Conformance = d.getRowConformance(row, columnMap, matter.TableColumnConformance)
var a string
a, err = readRowASCIIDocString(row, columnMap, matter.TableColumnAccess)
if err != nil {
return
}
var q string
q, err = readRowASCIIDocString(row, columnMap, matter.TableColumnQuality)
if err != nil {
return
}
cmd.Quality = parseQuality(q, types.EntityTypeCommand, d, row)
cmd.Access, _ = ParseAccess(a, types.EntityTypeCommand)
commands = append(commands, cmd)
commandMap[strings.ToLower(cmd.Name)] = cmd
cmd.Conformance = d.getRowConformance(row, columnMap, matter.TableColumnConformance)
var a string
a, err = readRowASCIIDocString(row, columnMap, matter.TableColumnAccess)
if err != nil {
return nil, err
}

for _, cmd := range commands {
if cmd.Response != "" {
if responseCommand, ok := commandMap[strings.ToLower(cmd.Response)]; ok && responseCommand.Access.Invoke == matter.PrivilegeUnknown {
responseCommand.Access.Invoke = cmd.Access.Invoke
}
}
var q string
q, err = readRowASCIIDocString(row, columnMap, matter.TableColumnQuality)
if err != nil {
return nil, err
}
return
cmd.Quality = parseQuality(q, types.EntityTypeCommand, d, row)
cmd.Access, _ = ParseAccess(a, types.EntityTypeCommand)
return cmd, nil
}

func (s *Section) toCommand(d *Doc, commandMap map[string]*matter.Command, entityMap map[asciidoc.Attributable][]types.Entity) (*matter.Command, error) {
name := strings.ToLower(text.TrimCaseInsensitiveSuffix(s.Name, " Command"))
c, ok := commandMap[name]
if !ok {
// Command sometimes have an parenthetical abbreviation after their name
name = parentheticalExpressionPattern.ReplaceAllString(name, "")
c, ok = commandMap[name]
if !ok {
slog.Warn("unknown command", log.Element("path", d.Path, s.Base), "command", s.Name)
return nil, nil
}
}

func (cf *commandFactory) Details(d *Doc, s *Section, entityMap map[asciidoc.Attributable][]types.Entity, c *matter.Command) (err error) {
c.Description = getDescription(d, s.Elements())

var rows []*asciidoc.TableRow
var headerRowIndex int
var columnMap ColumnIndex
var err error
rows, headerRowIndex, columnMap, _, err = parseFirstTable(d, s)
if err != nil {
if err == ErrNoTableFound {
err = nil
} else {
slog.Warn("No valid command parameter table found", log.Element("path", d.Path, s.Base), "command", name)
slog.Warn("No valid command parameter table found", log.Element("path", d.Path, s.Base), "command", c.Name)
err = nil
}
return nil, nil
return
}
c.Fields, err = d.readFields(headerRowIndex, rows, columnMap, types.EntityTypeCommandField)
if err != nil {
return nil, err
return
}
fieldMap := make(map[string]*matter.Field, len(c.Fields))
for _, f := range c.Fields {
fieldMap[f.Name] = f
}
err = s.mapFields(fieldMap, entityMap)
if err != nil {
return nil, err
return
}
c.Name = CanonicalName(c.Name)
return c, nil
return
}

func (cf *commandFactory) EntityName(s *Section) string {
name := strings.ToLower(text.TrimCaseInsensitiveSuffix(s.Name, " Command"))
return parentheticalExpressionPattern.ReplaceAllString(name, "")
}

func (cf *commandFactory) Children(d *Doc, s *Section) iter.Seq[*Section] {
return func(yield func(*Section) bool) {
parse.SkimFunc(s.Elements(), func(s *Section) bool {
if s.SecType != matter.SectionCommand {
return false
}
return !yield(s)
})
}
}

func (s *Section) toCommands(d *Doc, entityMap map[asciidoc.Attributable][]types.Entity) (commands matter.CommandSet, err error) {

t := FindFirstTable(s)
if t == nil {
return nil, nil
}

var cf commandFactory
commands, err = buildList(d, s, t, entityMap, commands, &cf)

for _, cmd := range commands {
if cmd.Response != "" {
for _, rc := range commands {
if strings.EqualFold(cmd.Response, rc.Name) {
rc.Access.Invoke = cmd.Access.Invoke
break
}
}
}
}

return
}

func ParseCommandDirection(s string) matter.Interface {
Expand Down
6 changes: 1 addition & 5 deletions matter/spec/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type Doc struct {
errata *errata.Errata
}

func NewDoc(d *asciidoc.Document, path Path) (*Doc, error) {
func newDoc(d *asciidoc.Document, path Path) (*Doc, error) {
doc := &Doc{
Base: d,
Path: path,
Expand Down Expand Up @@ -192,7 +192,3 @@ func (doc *Doc) Reference(ref string) (types.Entity, bool) {
}
return entities[0], true
}

func GithubSettings() []asciidoc.AttributeName {
return []asciidoc.AttributeName{asciidoc.AttributeName("env-github")}
}
Loading

0 comments on commit 1ada52f

Please sign in to comment.