mirror of
https://github.com/golang/go
synced 2024-11-22 07:04:40 -07:00
template: finally fix space handling around actions.
Rewrite the code to express the intention more clearly. Fixes #1042. R=rsc CC=golang-dev https://golang.org/cl/2011046
This commit is contained in:
parent
da25964e9e
commit
b5664ee320
@ -216,10 +216,9 @@ func equal(s []byte, n int, t []byte) bool {
|
|||||||
// item is empty, we are at EOF. The item will be either a
|
// item is empty, we are at EOF. The item will be either a
|
||||||
// delimited string or a non-empty string between delimited
|
// delimited string or a non-empty string between delimited
|
||||||
// strings. Tokens stop at (but include, if plain text) a newline.
|
// strings. Tokens stop at (but include, if plain text) a newline.
|
||||||
// Action tokens on a line by themselves drop the white space on
|
// Action tokens on a line by themselves drop any space on
|
||||||
// either side, up to and including the newline.
|
// either side, up to and including the newline.
|
||||||
func (t *Template) nextItem() []byte {
|
func (t *Template) nextItem() []byte {
|
||||||
special := false // is this a {.foo} directive, which means trim white space?
|
|
||||||
startOfLine := t.p == 0 || t.buf[t.p-1] == '\n'
|
startOfLine := t.p == 0 || t.buf[t.p-1] == '\n'
|
||||||
start := t.p
|
start := t.p
|
||||||
var i int
|
var i int
|
||||||
@ -233,7 +232,7 @@ func (t *Template) nextItem() []byte {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leadingWhite := i > start
|
leadingSpace := i > start
|
||||||
// What's left is nothing, newline, delimited string, or plain text
|
// What's left is nothing, newline, delimited string, or plain text
|
||||||
Switch:
|
Switch:
|
||||||
switch {
|
switch {
|
||||||
@ -242,28 +241,50 @@ Switch:
|
|||||||
case t.buf[i] == '\n':
|
case t.buf[i] == '\n':
|
||||||
newline()
|
newline()
|
||||||
case equal(t.buf, i, t.ldelim):
|
case equal(t.buf, i, t.ldelim):
|
||||||
// Delete surrounding white space if this {.foo} is the first thing on the line.
|
left := i // Start of left delimiter.
|
||||||
i += len(t.ldelim) // position after delimiter
|
right := -1 // Will be (immediately after) right delimiter.
|
||||||
special = i+1 < len(t.buf) && (t.buf[i] == '.' || t.buf[i] == '#')
|
haveText := false // Delimiters contain text.
|
||||||
if special && startOfLine {
|
i += len(t.ldelim)
|
||||||
start = i - len(t.ldelim)
|
// Find the end of the action.
|
||||||
} else if leadingWhite {
|
|
||||||
// not trimming space: return leading white space if there is some.
|
|
||||||
i -= len(t.ldelim)
|
|
||||||
t.p = i
|
|
||||||
return t.buf[start:i]
|
|
||||||
}
|
|
||||||
for ; i < len(t.buf); i++ {
|
for ; i < len(t.buf); i++ {
|
||||||
if t.buf[i] == '\n' {
|
if t.buf[i] == '\n' {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if equal(t.buf, i, t.rdelim) {
|
if equal(t.buf, i, t.rdelim) {
|
||||||
i += len(t.rdelim)
|
i += len(t.rdelim)
|
||||||
break Switch
|
right = i
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
haveText = true
|
||||||
}
|
}
|
||||||
|
if right < 0 {
|
||||||
t.parseError("unmatched opening delimiter")
|
t.parseError("unmatched opening delimiter")
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
// Is this a special action (starts with '.' or '#') and the only thing on the line?
|
||||||
|
if startOfLine && haveText {
|
||||||
|
firstChar := t.buf[left+len(t.ldelim)]
|
||||||
|
if firstChar == '.' || firstChar == '#' {
|
||||||
|
// It's special and the first thing on the line. Is it the last?
|
||||||
|
for j := right; j < len(t.buf) && white(t.buf[j]); j++ {
|
||||||
|
if t.buf[j] == '\n' {
|
||||||
|
// Yes it is. Drop the surrounding space and return the {.foo}
|
||||||
|
t.linenum++
|
||||||
|
t.p = j + 1
|
||||||
|
return t.buf[left:right]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No it's not. If there's leading space, return that.
|
||||||
|
if leadingSpace {
|
||||||
|
// not trimming space: return leading white space if there is some.
|
||||||
|
t.p = left
|
||||||
|
return t.buf[start:left]
|
||||||
|
}
|
||||||
|
// Return the word, leave the trailing space.
|
||||||
|
start = left
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
for ; i < len(t.buf); i++ {
|
for ; i < len(t.buf); i++ {
|
||||||
if t.buf[i] == '\n' {
|
if t.buf[i] == '\n' {
|
||||||
@ -276,15 +297,6 @@ Switch:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
item := t.buf[start:i]
|
item := t.buf[start:i]
|
||||||
if special && startOfLine {
|
|
||||||
// consume trailing white space
|
|
||||||
for ; i < len(t.buf) && white(t.buf[i]); i++ {
|
|
||||||
if t.buf[i] == '\n' {
|
|
||||||
newline()
|
|
||||||
break // stop before newline
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.p = i
|
t.p = i
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,7 @@ var tests = []*Test{
|
|||||||
&Test{" {.tab} \n", "\t", ""},
|
&Test{" {.tab} \n", "\t", ""},
|
||||||
&Test{" {#comment} \n", "", ""},
|
&Test{" {#comment} \n", "", ""},
|
||||||
&Test{"\tSome Text\t\n", "\tSome Text\t\n", ""},
|
&Test{"\tSome Text\t\n", "\tSome Text\t\n", ""},
|
||||||
|
&Test{" {.meta-right} {.meta-right} {.meta-right} \n", " } } } \n", ""},
|
||||||
|
|
||||||
// Variables at top level
|
// Variables at top level
|
||||||
&Test{
|
&Test{
|
||||||
|
Loading…
Reference in New Issue
Block a user