tools: fix 'Split called after Scan'

Change-Id: I2dae23440d33fa830107575987805e858e4bf4a7
Reviewed-on: https://go-review.googlesource.com/22749
Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
Francesc Campoy 2016-05-01 06:45:43 -07:00 committed by Francesc Campoy Flores
parent 8dab6f1129
commit 0b2f4dcf4d
1 changed files with 33 additions and 47 deletions

View File

@ -7,7 +7,6 @@
package main // import "golang.org/x/tools/cmd/html2article" package main // import "golang.org/x/tools/cmd/html2article"
import ( import (
"bufio"
"bytes" "bytes"
"errors" "errors"
"flag" "flag"
@ -39,7 +38,9 @@ func convert(w io.Writer, r io.Reader) error {
} }
style := find(root, isTag(atom.Style)) style := find(root, isTag(atom.Style))
parseStyles(style) if err := parseStyles(style); err != nil {
log.Printf("couldn't parse all styles: %v", err)
}
body := find(root, isTag(atom.Body)) body := find(root, isTag(atom.Body))
if body == nil { if body == nil {
@ -60,59 +61,44 @@ const (
var cssRules = make(map[string]Style) var cssRules = make(map[string]Style)
func parseStyles(style *html.Node) { func parseStyles(style *html.Node) error {
if style == nil || style.FirstChild == nil { if style == nil || style.FirstChild == nil {
log.Println("couldn't find styles") return errors.New("couldn't find styles")
return
}
s := bufio.NewScanner(strings.NewReader(style.FirstChild.Data))
findRule := func(b []byte, atEOF bool) (advance int, token []byte, err error) {
if i := bytes.Index(b, []byte("{")); i >= 0 {
token = bytes.TrimSpace(b[:i])
advance = i
}
return
}
findBody := func(b []byte, atEOF bool) (advance int, token []byte, err error) {
if len(b) == 0 {
return
}
if b[0] != '{' {
err = fmt.Errorf("expected {, got %c", b[0])
return
}
if i := bytes.Index(b, []byte("}")); i < 0 {
err = fmt.Errorf("can't find closing }")
return
} else {
token = b[1:i]
advance = i + 1
}
return
} }
s.Split(findRule) styles := style.FirstChild.Data
for s.Scan() { readUntil := func(end rune) (string, bool) {
rule := s.Text() i := strings.IndexRune(styles, end)
s.Split(findBody) if i < 0 {
if !s.Scan() { return "", false
}
s := styles[:i]
styles = styles[i:]
return s, true
}
for {
sel, ok := readUntil('{')
if !ok && sel == "" {
break break
} else if !ok {
return fmt.Errorf("could not parse selector %q", styles)
}
value, ok := readUntil('}')
if !ok {
return fmt.Errorf("couldn't parse style body for %s", sel)
} }
b := strings.ToLower(s.Text())
switch { switch {
case strings.Contains(b, "italic"): case strings.Contains(value, "italic"):
cssRules[rule] = Italic cssRules[sel] = Italic
case strings.Contains(b, "bold"): case strings.Contains(value, "bold"):
cssRules[rule] = Bold cssRules[sel] = Bold
case strings.Contains(b, "Consolas") || strings.Contains(b, "Courier New"): case strings.Contains(value, "Consolas") || strings.Contains(value, "Courier New"):
cssRules[rule] = Code cssRules[sel] = Code
} }
s.Split(findRule)
}
if err := s.Err(); err != nil {
log.Println(err)
} }
return nil
} }
var newlineRun = regexp.MustCompile(`\n\n+`) var newlineRun = regexp.MustCompile(`\n\n+`)