Skip to content

Commit

Permalink
hugolib: Use []byte in shortcode parsing
Browse files Browse the repository at this point in the history
See #5324
  • Loading branch information
bep committed Oct 22, 2018
1 parent 27f5a90 commit 1b7ecfc
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 25 deletions.
2 changes: 1 addition & 1 deletion hugolib/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -1871,7 +1871,7 @@ func (p *Page) SaveSource() error {
// TODO(bep) lazy consolidate
func (p *Page) processShortcodes() error {
p.shortcodeState = newShortcodeHandler(p)
tmpContent, err := p.shortcodeState.extractShortcodes(string(p.workContent), p.withoutContent())
tmpContent, err := p.shortcodeState.extractShortcodes(p.workContent, p.withoutContent())
if err != nil {
return err
}
Expand Down
24 changes: 13 additions & 11 deletions hugolib/shortcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,9 @@ Loop:

return sc, nil
case currItem.IsText():
sc.inner = append(sc.inner, currItem.Val)
sc.inner = append(sc.inner, currItem.ValStr())
case currItem.IsShortcodeName():
sc.name = currItem.Val
sc.name = currItem.ValStr()
// We pick the first template for an arbitrary output format
// if more than one. It is "all inner or no inner".
tmpl := getShortcodeTemplateForTemplateKey(scKey{}, sc.name, p.s.Tmpl)
Expand All @@ -576,11 +576,11 @@ Loop:
// named params
if sc.params == nil {
params := make(map[string]string)
params[currItem.Val] = pt.Next().Val
params[currItem.ValStr()] = pt.Next().ValStr()
sc.params = params
} else {
if params, ok := sc.params.(map[string]string); ok {
params[currItem.Val] = pt.Next().Val
params[currItem.ValStr()] = pt.Next().ValStr()
} else {
return sc, errShortCodeIllegalState
}
Expand All @@ -590,11 +590,11 @@ Loop:
// positional params
if sc.params == nil {
var params []string
params = append(params, currItem.Val)
params = append(params, currItem.ValStr())
sc.params = params
} else {
if params, ok := sc.params.([]string); ok {
params = append(params, currItem.Val)
params = append(params, currItem.ValStr())
sc.params = params
} else {
return sc, errShortCodeIllegalState
Expand All @@ -613,19 +613,21 @@ Loop:
return sc, nil
}

func (s *shortcodeHandler) extractShortcodes(stringToParse string, p *PageWithoutContent) (string, error) {
var shortCodeStart = []byte("{{")

startIdx := strings.Index(stringToParse, "{{")
func (s *shortcodeHandler) extractShortcodes(input []byte, p *PageWithoutContent) (string, error) {

startIdx := bytes.Index(input, shortCodeStart)

// short cut for docs with no shortcodes
if startIdx < 0 {
return stringToParse, nil
return string(input), nil
}

// the parser takes a string;
// since this is an internal API, it could make sense to use the mutable []byte all the way, but
// it seems that the time isn't really spent in the byte copy operations, and the impl. gets a lot cleaner
pt := pageparser.ParseFrom(stringToParse, startIdx)
pt := pageparser.ParseFrom(input, startIdx)

result := bp.GetBuffer()
defer bp.PutBuffer(result)
Expand All @@ -642,7 +644,7 @@ Loop:

switch {
case currItem.IsText():
result.WriteString(currItem.Val)
result.WriteString(currItem.ValStr())
case currItem.IsLeftShortcodeDelim():
// let extractShortcode handle left delim (will do so recursively)
pt.Backup()
Expand Down
2 changes: 1 addition & 1 deletion hugolib/shortcode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ func TestExtractShortcodes(t *testing.T) {
return fmt.Sprintf("HAHA%s-%dHBHB", shortcodePlaceholderPrefix, counter)
}

content, err := s.extractShortcodes(this.input, p.withoutContent())
content, err := s.extractShortcodes([]byte(this.input), p.withoutContent())

if b, ok := this.expect.(bool); ok && !b {
if err == nil {
Expand Down
4 changes: 4 additions & 0 deletions parser/pageparser/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ type Item struct {
Val []byte
}

func (i Item) ValStr() string {
return string(i.Val)
}

func (i Item) IsText() bool {
return i.typ == tText
}
Expand Down
11 changes: 0 additions & 11 deletions parser/pageparser/pagelexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,6 @@ type pageLexer struct {
items []Item
}

func Parse(s string) *Tokens {
return ParseFrom(s, 0)
}

func ParseFrom(s string, from int) *Tokens {
input := []byte(s)
lexer := newPageLexer(input, pos(from), lexMainSection) // TODO(bep) 2errors
lexer.run()
return &Tokens{lexer: lexer}
}

// note: the input position here is normally 0 (start), but
// can be set if position of first shortcode is known
// TODO(bep) 2errors byte
Expand Down
10 changes: 9 additions & 1 deletion parser/pageparser/pageparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@
// See slides here: http://cuddle.googlecode.com/hg/talk/lex.html
package pageparser

// The lexical scanning below
func Parse(input []byte) *Tokens {
return ParseFrom(input, 0)
}

func ParseFrom(input []byte, from int) *Tokens {
lexer := newPageLexer(input, pos(from), lexMainSection) // TODO(bep) 2errors
lexer.run()
return &Tokens{lexer: lexer}
}

type Tokens struct {
lexer *pageLexer
Expand Down

0 comments on commit 1b7ecfc

Please sign in to comment.