Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize template replacement speed #34

Merged
merged 6 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions ImageProcesser.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,20 @@ func processImage(img *Image) (imgXMLStr string, err error) {
imgExt := strings.TrimLeft(strings.ToLower(path.Ext(imgPath)), ".")
contentTypesName := "[Content_Types].xml"
contentTypesNode := t.fileToXMLStruct(contentTypesName)
for _, node := range contentTypesNode.Nodes {
contentTypesNode.iterate(func(node *xmlNode) bool {
if strings.ToLower(node.Attr("Extension")) == imgExt {
isContainType = true
return true
}
}
return false
})
if !isContainType {
contentTypesNode.Nodes = append(contentTypesNode.Nodes, &xmlNode{
contentTypesNode.addSub(&xmlNode{
XMLName: xml.Name{
Space: "",
Local: "Default",
},
Attrs: []*xml.Attr{
Attrs: []xml.Attr{
{Name: xml.Name{Space: "", Local: "Extension"}, Value: imgExt},
{Name: xml.Name{Space: "", Local: "ContentType"}, Value: "image/" + imgExt},
},
Expand All @@ -70,13 +72,13 @@ func processImage(img *Image) (imgXMLStr string, err error) {
} else {
relNode = t.fileToXMLStruct(relName)
}
rid := fmt.Sprintf("rId%d", len(relNode.Nodes)+1)
relNode.Nodes = append(relNode.Nodes, &xmlNode{
rid := fmt.Sprintf("rId%d", relNode.childLenght+1)
relNode.addSub(&xmlNode{
XMLName: xml.Name{
Space: "",
Local: "Relationship",
},
Attrs: []*xml.Attr{
Attrs: []xml.Attr{
{Name: xml.Name{Space: "", Local: "Id"}, Value: rid},
{Name: xml.Name{Space: "", Local: "Type"}, Value: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"},
{Name: xml.Name{Space: "", Local: "Target"}, Value: "media/" + imgPath},
Expand Down
12 changes: 6 additions & 6 deletions Param.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type Param struct {
Trigger *ParamTrigger

RowPlaceholder string
Index int //slice data index,expandPlaceholders function needs
}

// NewParam ..
Expand Down Expand Up @@ -238,7 +239,7 @@ func (p *Param) RunTrigger(xnode *xmlNode) {
}

n := xnode.closestUp(ntypes)
if n == nil || n.isDeleted {
if n == nil {
// aurora.Red("EMPTY parent of %v", xnode.Tag())
return
}
Expand All @@ -250,24 +251,23 @@ func (p *Param) RunTrigger(xnode *xmlNode) {
isListRemove = isListRemove || (isListItem && p.Trigger.Scope == TriggerScopeSection) // :section
if isListRemove && isListItem {
// find all list items as this
for _, wpNode := range n.parent.Nodes {
n.parent.childFirst.iterate(func(wpNode *xmlNode) bool {
isitem, listid := wpNode.IsListItem()
if !isitem || listid != listID {
// aurora.Red("--- %s [%s]", wpNode, wpNode.AllContents())
continue
return false
}
if p.Trigger.Command == TriggerCommandRemove {
wpNode.Nodes = nil
wpNode.delete()
}
}
return false
})
return
}

// Simple cases
if p.Trigger.Command == TriggerCommandRemove {
// fmt.Printf("Trigger: [%s] [%s]\t Command=[%s]\n", aurora.Blue(p.AbsoluteKey), aurora.Magenta(p.Trigger.String()), aurora.BgMagenta(p.Trigger.Command))
n.Nodes = nil
n.delete()
return
}
Expand Down
61 changes: 61 additions & 0 deletions ParamList.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"reflect"
"regexp"
"strings"
)

// ParamList ..
Expand Down Expand Up @@ -244,3 +245,63 @@ func (params ParamList) Walk(fn func(*Param)) {
p.Walk(fn, p.Level+1)
}
}

func (params ParamList) WalkWithEnd(fn func(*Param) bool) {
for _, p := range params {
if fn(p) {
continue
}
p.Params.WalkWithEnd(fn)
}
}

func (p ParamList) FindAllByKey(key string) []*Param {
keySlice := strings.Split(key, ".")
var ret []*Param
p.findAllByKey(nil, nil, 0, 1, keySlice, &ret)
return ret
}

func (p ParamList) findAllByKey(privParamList, paramList []int, offset, depth int, key []string, params *[]*Param) ([]int, int) {
if depth > len(key) {
return nil, 0
}
currLev := strings.Join(key[:depth], ".")
for i, param := range p {
curr := make([]int, len(paramList))
copy(curr, paramList)
if param.parent != nil && param.parent.Type == SliceParam {
curr = append(curr, i+1)
}
if param.Type == StructParam {
privParamList, offset = param.Params.findAllByKey(privParamList, curr, offset, depth+1, key, params)
} else {
if param.CompactKey == currLev || param.AbsoluteKey == currLev {
if param.Type == SliceParam {
privParamList, offset = param.Params.findAllByKey(privParamList, curr, offset, depth, key, params)
continue
}
if depth == len(key) {
index := 1
if len(curr) > 0 {
index = curr[len(curr)-1]
if len(curr) == len(privParamList) {
for i := range curr[:len(curr)-1] {
if privParamList[i] != curr[i] {
offset += privParamList[len(privParamList)-1]
break
}
}
}
}
param.Index = index + offset
privParamList = curr
*params = append(*params, param)
} else {
privParamList, offset = param.Params.findAllByKey(privParamList, curr, offset, depth+1, key, params)
}
}
}
}
return privParamList, offset
}
44 changes: 19 additions & 25 deletions Template.helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (t *Template) bytesToXMLStruct(buf []byte) *xmlNode {
buf = bytes.ReplaceAll(buf, []byte("</v:"), []byte("</v-"))

xdocNode := &xmlNode{}
if err := xml.Unmarshal(buf, &xdocNode); err != nil {
if err := xml.Unmarshal(buf, xdocNode); err != nil {
log.Printf("fileToXMLStruct: %v", err)
}

Expand All @@ -29,10 +29,13 @@ func (t *Template) bytesToXMLStruct(buf []byte) *xmlNode {
if xnode.Tag() == "w-body" {
xnode.parent = xdocNode
}

for _, n := range xnode.Nodes {
n.parent = xnode
if xnode.childFirst != nil {
xnode.childFirst.iterate(func(node *xmlNode) bool {
node.parent = xnode
return false
})
}

})

// log.Printf("%s", structToXMLBytes(n))
Expand Down Expand Up @@ -71,13 +74,13 @@ func (t *Template) replaceImageParams(xnode *xmlNode, param *Param) {
parent: xnode.parent,
isNew: true,
}
xnode.parent.Nodes = append(xnode.parent.Nodes, contentNode)
xnode.add(contentNode)
}
// image node
if len(contentSlice)-i > 1 {
imgNode := t.bytesToXMLStruct([]byte(param.Value))
imgNode.parent = xnode.parent
xnode.parent.Nodes = append(xnode.parent.Nodes, imgNode)
xnode.add(imgNode)
}
}
// Empty the content before deleting to prevent reprocessing when params walk
Expand Down Expand Up @@ -121,32 +124,23 @@ func (t *Template) matchBrokenRightPlaceholder(content string) bool {
return t.matchBrokenPlaceholder(content, false)
}

func (t Template) GetContentPrefixList(content []byte) []string {
func (t Template) GetAttrParam(attr string) []string {
var ret []string
var record strings.Builder
start := false
length := len(content)
for i, v := range content {
if i == 0 {
continue
}

if v == '{' && content[i-1] == '{' {
length := len(attr)
for i := 1; i < length-1; i++ {
if attr[i] == '{' && attr[i-1] == '{' {
start = true
continue
}
if start && (attr[i] == ' ' || (attr[i] == '}' && length-1 > i && attr[i+1] == '}')) {
ret = append(ret, record.String())
record.Reset()
start = false
}
if start {
if v == ' ' || (v == '}' && length-1 > i && content[i+1] == '}') {
ret = append(ret, record.String())
record.Reset()
start = false
}
if v == '.' {
ret = append(ret, record.String())
record.Reset()
continue
}
record.WriteByte(v)
record.WriteByte(attr[i])
}
}
return ret
Expand Down
Loading
Loading