package d2ir
import (
"strings"
"github.com/pancsta/d2/d2ast"
)
func (m *Map ) multiGlob (pattern []string , visit func (*Field ) bool ) ([]*Field , bool ) {
var fa []*Field
if d2ast .IsDoubleGlob (pattern ) {
m ._doubleGlob (&fa , visit )
return fa , true
}
if d2ast .IsTripleGlob (pattern ) {
m ._tripleGlob (&fa , visit )
return fa , true
}
return nil , false
}
func (m *Map ) pathToField (target *Field ) []*Field {
var reverse []*Field
for current := target ; current != nil ; {
parent := ParentMap (current )
if parent == nil {
return nil
}
reverse = append (reverse , current )
if parent == m {
path := make ([]*Field , len (reverse ))
for i := range reverse {
path [len (reverse )-1 -i ] = reverse [i ]
}
return path
}
current = ParentField (parent )
}
return nil
}
func (m *Map ) directChildToward (target *Field ) *Field {
path := m .pathToField (target )
if len (path ) == 0 {
return nil
}
return path [0 ]
}
func (m *Map ) multiGlobMatchesToward (target *Field , pattern []string , visit func (*Field ) bool ) []*Field {
path := m .pathToField (target )
if len (path ) == 0 {
return nil
}
var matches []*Field
if d2ast .IsDoubleGlob (pattern ) {
_doubleGlobField (path [0 ], &matches , visit )
return matches
}
if d2ast .IsTripleGlob (pattern ) {
_tripleGlobField (path [0 ], &matches , visit )
return matches
}
return nil
}
func _doubleGlobField(f *Field , matches *[]*Field , visit func (*Field ) bool ) bool {
if f == nil || f .Name == nil {
return true
}
if visit != nil && !visit (f ) {
return false
}
name := f .Name .ScalarString ()
if _ , reserved := d2ast .ReservedKeywords [name ]; reserved && f .Name .IsUnquoted () {
if skipDoubleGlobSubtree (name ) {
return true
}
if f .Map () != nil {
return f .Map ()._doubleGlob (matches , visit )
}
return true
}
if NodeBoardKind (f ) == "" {
*matches = append (*matches , f )
}
if f .Map () != nil {
return f .Map ()._doubleGlob (matches , visit )
}
return true
}
func skipDoubleGlobSubtree(name string ) bool {
if _ , board := d2ast .BoardKeywords [name ]; board {
return true
}
return name == "classes" || name == "vars"
}
func _tripleGlobField(f *Field , matches *[]*Field , visit func (*Field ) bool ) bool {
if f == nil || f .Name == nil {
return true
}
if visit != nil && !visit (f ) {
return false
}
name := f .Name .ScalarString ()
if _ , reserved := d2ast .ReservedKeywords [name ]; reserved && f .Name .IsUnquoted () {
if _ , board := d2ast .BoardKeywords [name ]; !board {
return true
}
if f .Map () != nil {
return f .Map ()._tripleGlob (matches , visit )
}
return true
}
if NodeBoardKind (f ) == "" {
*matches = append (*matches , f )
}
if f .Map () != nil {
return f .Map ()._tripleGlob (matches , visit )
}
return true
}
func (m *Map ) _doubleGlob (fa *[]*Field , visit func (*Field ) bool ) bool {
for _ , f := range m .Fields {
if visit != nil && !visit (f ) {
return false
}
if f .Name == nil {
continue
}
name := f .Name .ScalarString ()
if _ , ok := d2ast .ReservedKeywords [name ]; ok && f .Name .IsUnquoted () {
if skipDoubleGlobSubtree (name ) {
continue
}
if f .Map () != nil {
if !f .Map ()._doubleGlob (fa , visit ) {
return false
}
}
continue
}
if NodeBoardKind (f ) == "" {
*fa = append (*fa , f )
}
if f .Map () != nil {
if !f .Map ()._doubleGlob (fa , visit ) {
return false
}
}
}
return true
}
func (m *Map ) _tripleGlob (fa *[]*Field , visit func (*Field ) bool ) bool {
for _ , f := range m .Fields {
if visit != nil && !visit (f ) {
return false
}
if f == nil || f .Name == nil {
continue
}
if _ , ok := d2ast .ReservedKeywords [f .Name .ScalarString ()]; ok && f .Name .IsUnquoted () {
if _ , ok := d2ast .BoardKeywords [f .Name .ScalarString ()]; !ok {
continue
}
if f .Map () != nil {
if !f .Map ()._tripleGlob (fa , visit ) {
return false
}
}
continue
}
if NodeBoardKind (f ) == "" {
*fa = append (*fa , f )
}
if f .Map () != nil {
if !f .Map ()._tripleGlob (fa , visit ) {
return false
}
}
}
return true
}
func matchPattern(s string , pattern []string ) bool {
if len (pattern ) == 0 {
return true
}
if _ , ok := d2ast .ReservedKeywords [s ]; ok {
return false
}
for i := 0 ; i < len (pattern ); i ++ {
if pattern [i ] == "*" {
if i == len (pattern )-1 {
return true
}
next := strings .ToLower (pattern [i +1 ])
lowerS := strings .ToLower (s )
if i +1 == len (pattern )-1 {
return strings .HasSuffix (lowerS , next )
}
j := strings .Index (lowerS , next )
if j == -1 {
return false
}
s = s [j +len (pattern [i +1 ]):]
i ++
} else {
if !strings .HasPrefix (strings .ToLower (s ), strings .ToLower (pattern [i ])) {
return false
}
s = s [len (pattern [i ]):]
}
}
return s == ""
}
The pages are generated with Golds v0.8.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .