Skip to content

Commit

Permalink
refactor(parser): section title parsing (#1037)
Browse files Browse the repository at this point in the history
first parse with substitutions already enabled, then only re-parse if title contains attribute refs

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon authored Jun 6, 2022
1 parent 8f0b39c commit c3e86f3
Show file tree
Hide file tree
Showing 10 changed files with 31,185 additions and 27,562 deletions.
18 changes: 12 additions & 6 deletions pkg/parser/attributes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,14 @@ var _ = Describe("attributes", func() {
&types.Section{
Level: 1,
Attributes: types.Attributes{
types.AttrID: "custom",
types.AttrRoles: types.Roles{"cookie"},
types.AttrID: "custom",
types.AttrCustomID: true,
types.AttrRoles: types.Roles{"cookie"},
},
Title: []interface{}{
types.RawLine("Section A"),
&types.StringElement{
Content: "Section A",
},
},
},
},
Expand All @@ -368,11 +371,14 @@ var _ = Describe("attributes", func() {
&types.Section{
Level: 1,
Attributes: types.Attributes{
types.AttrID: "custom",
types.AttrRoles: types.Roles{"cookie"},
types.AttrID: "custom",
types.AttrCustomID: true,
types.AttrRoles: types.Roles{"cookie"},
},
Title: []interface{}{
types.RawLine("Section A"),
&types.StringElement{
Content: "Section A",
},
},
},
},
Expand Down
67 changes: 59 additions & 8 deletions pkg/parser/document_processing_apply_substitutions.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,65 @@ func applySubstitutionsOnDocumentHeader(ctx *ParseContext, b *types.DocumentHead
}

func applySubstitutionsOnWithTitle(ctx *ParseContext, b types.WithTitle, opts ...Option) error {
log.Debugf("processing element with title of type '%T' in 3 steps", b)
log.Debugf("processing element with title of type '%T'", b)
if err := applySubstitutionsOnAttributes(ctx, b, headerSubstitutions()); err != nil {
return err
}
opts = append(opts, Entrypoint("HeaderGroup"))
// apply until Attribute substitution included
// TODO: parse InlinePassthroughs and Attributes in the first pass (instead of dumb raw content)
title, err := processSubstitutions(ctx, b.GetTitle(), headerSubstitutions(), opts...)
if err != nil {
return err
// only reparse only if title contains attribute references
if hasAttributeReferenceInSlice(b.GetTitle()) {
opts = append(opts, Entrypoint("HeaderGroup"))
title, err := replaceAttributeRefsAndReparse(ctx, b.GetTitle(), headerSubstitutions()[2:], opts...)
if err != nil {
return err
}
b.SetTitle(title)
}
return b.SetTitle(title)
return nil
}

func hasAttributeReferenceInSlice(elements []interface{}) bool {
for _, e := range elements {
switch e := e.(type) {
case *types.AttributeReference:
log.Debug("found an attribute reference")
return true
case types.WithElements:
if hasAttributeReferenceInAttributes(e.GetAttributes()) {
log.Debug("found an attribute reference in an element attributes")
return true
}
if hasAttributeReferenceInSlice(e.GetElements()) {
log.Debug("found an attribute reference in an element")
return true
}
case types.WithAttributes:
if hasAttributeReferenceInAttributes(e.GetAttributes()) {
log.Debug("found an attribute reference in an element attributes")
return true
}
}
}
return false
}

func hasAttributeReferenceInAttributes(attrs types.Attributes) bool {
for _, v := range attrs {
switch v := v.(type) {
case []interface{}:
if hasAttributeReferenceInSlice(v) {
return true
}
case types.Roles:
if hasAttributeReferenceInSlice(v) {
return true
}
case types.Options:
if hasAttributeReferenceInSlice(v) {
return true
}
}
}
return false
}

func applySubstitutionsOnTable(ctx *ParseContext, t *types.Table, opts ...Option) error {
Expand Down Expand Up @@ -327,6 +374,7 @@ func replaceAttributeRefsAndReparse(ctx *ParseContext, elements []interface{}, s
return elements, nil
}

// TODO: return bool to see if an attribute ref was replaced
func applySubstitutionsOnAttributes(ctx *ParseContext, b types.WithAttributes, subs []string) error {
if log.IsLevelEnabled(log.DebugLevel) {
log.Debugf("applying substitutions in attributes of element of type '%T':\n%s", b, spew.Sdump(b.GetAttributes()))
Expand Down Expand Up @@ -621,6 +669,9 @@ func (c *current) isExperimentalEnabled() bool {
// ----------------------------------------------

func (c *current) lookupCurrentSubstitutions() ([]string, bool) {
if s, found := c.state[enabledSubstitutions].([]string); found {
return s, true
}
s, found := c.globalStore[enabledSubstitutions].([]string)
return s, found
}
Expand Down
34 changes: 32 additions & 2 deletions pkg/parser/document_processing_apply_substitutions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,24 @@ var _ = Describe("apply substitutions", func() {
},
},
Title: []interface{}{
types.RawLine("Document [.{role1}]*{title}*"),
&types.StringElement{
Content: "Document ",
},
&types.QuotedText{
Kind: "*",
Attributes: types.Attributes{
types.AttrRoles: types.Roles{
&types.AttributeReference{
Name: "role1",
},
},
},
Elements: []interface{}{
&types.StringElement{
Content: "Title",
},
},
},
},
Elements: []interface{}{
&types.DocumentAuthors{ // TODO: support attribute references in document authors
Expand Down Expand Up @@ -122,7 +139,20 @@ var _ = Describe("apply substitutions", func() {
},
},
Title: []interface{}{
types.RawLine("Section [.{role1}]*{title}*"),
&types.StringElement{
Content: "Section ",
},
&types.QuotedText{
Kind: types.SingleQuoteBold,
Attributes: types.Attributes{
types.AttrRoles: types.Roles{"role_1"},
},
Elements: []interface{}{
&types.StringElement{
Content: "Title",
},
},
},
},
},
},
Expand Down
4 changes: 3 additions & 1 deletion pkg/parser/document_processing_parse_fragments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,9 @@ on
&types.Section{
Level: 1,
Title: []interface{}{
types.RawLine("section title"),
&types.StringElement{
Content: "section title",
},
},
},
},
Expand Down
8 changes: 6 additions & 2 deletions pkg/parser/document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ Garrett D'Amore
Elements: []interface{}{
&types.DocumentHeader{
Title: []interface{}{
types.RawLine("My title"),
&types.StringElement{
Content: "My title",
},
},
Elements: []interface{}{
&types.AttributeDeclaration{
Expand Down Expand Up @@ -76,7 +78,9 @@ Garrett D'Amore
Elements: []interface{}{
&types.DocumentHeader{
Title: []interface{}{
types.RawLine("My title"),
&types.StringElement{
Content: "My title",
},
},
Elements: []interface{}{
&types.AttributeDeclaration{
Expand Down
Loading

0 comments on commit c3e86f3

Please sign in to comment.