Skip to content

Commit

Permalink
Better description generation for events and commands
Browse files Browse the repository at this point in the history
  • Loading branch information
hasty committed Jul 30, 2024
1 parent 6010cca commit 469158c
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 9 deletions.
5 changes: 1 addition & 4 deletions matter/spec/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,7 @@ func (s *Section) toCommands(d *Doc, entityMap map[asciidoc.Attributable][]types
}
}

var desc = parse.FindFirst[*asciidoc.String](s.Elements())
if desc != nil {
c.Description = strings.ReplaceAll(desc.Value, "\n", " ")
}
c.Description = getDescription(d, s.Elements())

var rows []*asciidoc.TableRow
var headerRowIndex int
Expand Down
5 changes: 1 addition & 4 deletions matter/spec/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ func (s *Section) toEvents(d *Doc, entityMap map[asciidoc.Attributable][]types.E
if err != nil {
return
}
e.Description, err = readRowASCIIDocString(row, columnMap, matter.TableColumnDescription)
if err != nil {
return
}
e.Priority, err = readRowASCIIDocString(row, columnMap, matter.TableColumnPriority)
if err != nil {
return
Expand Down Expand Up @@ -67,6 +63,7 @@ func (s *Section) toEvents(d *Doc, entityMap map[asciidoc.Attributable][]types.E
slog.Debug("unknown event", "event", name)
continue
}
e.Description = getDescription(d, s.Set)
var rows []*asciidoc.TableRow
var headerRowIndex int
var columnMap ColumnIndex
Expand Down
122 changes: 122 additions & 0 deletions matter/spec/text.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package spec

import (
"fmt"
"regexp"
"strconv"
"strings"

"github.com/project-chip/alchemy/asciidoc"
"github.com/project-chip/alchemy/matter"
)

var endOfSentencePattern = regexp.MustCompile(`(?m)(\.( |$)|\n\n)`)

func getDescription(doc *Doc, els asciidoc.Set) string {
var sb strings.Builder
readDescription(doc, els, &sb)
description := sb.String()
endOfSentence := endOfSentencePattern.FindStringIndex(description)
if endOfSentence != nil {
endOfSentenceIndex := endOfSentence[0]
if description[endOfSentenceIndex] == '.' {
endOfSentenceIndex++
}
description = description[:endOfSentenceIndex]
}
return description
}

func readDescription(doc *Doc, els asciidoc.Set, value *strings.Builder) (err error) {
var foundNonBlock bool
for _, el := range els {
var e asciidoc.Element
switch el := el.(type) {
case *Element:
e = el.Base
case asciidoc.Element:
e = el
default:
return
}

switch e.Type() {
case asciidoc.ElementTypeBlock, asciidoc.ElementTypeDocument:
if foundNonBlock {
return
}
continue
case asciidoc.ElementTypeAttribute, asciidoc.ElementTypeAttributes:
continue
}
foundNonBlock = true
switch el := e.(type) {
case *asciidoc.String:
value.WriteString(el.Value)
case asciidoc.FormattedTextElement:
err = readDescription(doc, el.Elements(), value)
case *asciidoc.CrossReference:
if len(el.Set) > 0 {
var label strings.Builder
readDescription(doc, el.Set, &label)
value.WriteString(strings.TrimSpace(label.String()))
} else {
var val string
anchor := doc.FindAnchor(el.ID)
if anchor != nil {
val = matter.StripTypeSuffixes(ReferenceName(anchor.Element))
} else {
val = strings.TrimPrefix(el.ID, "_")
val = strings.TrimPrefix(val, "ref_") // Trim, and hope someone else has it defined
}
value.WriteString(val)
}
case *asciidoc.Link:
value.WriteString(el.URL.Scheme)
readDescription(doc, el.URL.Path, value)
case *asciidoc.LinkMacro:
value.WriteString(el.URL.Scheme)
readDescription(doc, el.URL.Path, value)
case *asciidoc.Superscript:
// In the special case of superscript elements, we do checks to make sure it's not an asterisk or a footnote, which should be ignored
var quotedText strings.Builder
err = readDescription(doc, el.Elements(), &quotedText)
if err != nil {
return
}
qt := quotedText.String()
if qt == "*" { //
continue
}
_, parseErr := strconv.Atoi(qt)
if parseErr == nil {
// This is probably a footnote
// The similar buildConstraintValue method does not do this, as there are exponential values in contraints
continue
}
value.WriteString(qt)
case *asciidoc.SpecialCharacter:
value.WriteString(el.Character)
case *asciidoc.InlinePassthrough:
value.WriteString("+")
err = readDescription(doc, el.Elements(), value)
case *asciidoc.InlineDoublePassthrough:
value.WriteString("++")
err = readDescription(doc, el.Elements(), value)
case *asciidoc.ThematicBreak:
case asciidoc.EmptyLine:
case *asciidoc.NewLine:
value.WriteString(" ")
case asciidoc.HasElements:
err = readDescription(doc, el.Elements(), value)
case *asciidoc.LineBreak:
value.WriteString(" ")
default:
return fmt.Errorf("unexpected type in description: %T", el)
}
if err != nil {
return err
}
}
return nil
}
4 changes: 3 additions & 1 deletion zap/generate/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ func populateCommand(ce *etree.Element, c *matter.Command, errata *zap.Errata) {
de = etree.NewElement("description")
ce.Child = append([]etree.Token{de}, ce.Child...)
}
de.SetText(c.Description)
if len(c.Description) > 0 {
de.SetText(c.Description)
}

needsAccess := c.Access.Invoke != matter.PrivilegeUnknown && c.Access.Invoke != matter.PrivilegeOperate && c.Direction != matter.InterfaceClient
if needsAccess {
Expand Down
9 changes: 9 additions & 0 deletions zap/generate/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ func populateEvent(ee *etree.Element, e *matter.Event, cluster *matter.Cluster,
ee.RemoveAttr("optional")
}

de := ee.SelectElement("description")
if de == nil {
de = etree.NewElement("description")
ee.Child = append([]etree.Token{de}, ee.Child...)
}
if len(e.Description) > 0 {
de.SetText(e.Description)
}

fieldIndex := 0
fieldElements := ee.SelectElements("field")
for _, fe := range fieldElements {
Expand Down

0 comments on commit 469158c

Please sign in to comment.