gitweb - printer.go
1 package main
2
3 import (
4 "io"
5
6 "vimagination.zapto.org/memio"
7 "vimagination.zapto.org/parser"
8 "vimagination.zapto.org/rwcount"
9 )
10
11 const (
12 TokenUnknown parser.TokenType = iota
13 TokenComment
14 )
15
16 type Tokens struct {
17 Unknown, Comment parser.TokenType
18 }
19
20 var tokens = Tokens{
21 Unknown: TokenUnknown,
22 Comment: TokenComment,
23 }
24
25 func handleTemplate(file *File, w io.Writer, ch <-chan parser.Token, err chan<- error) {
26 err <- config.prettyTemplate.Execute(w, struct {
27 *File
28 Tokens <-chan parser.Token
29 TokenTypes *Tokens
30 }{
31 File: file,
32 Tokens: ch,
33 TokenTypes: &tokens,
34 })
35 }
36
37 func prettify(file *File, w io.Writer, r io.Reader, tf parser.TokenFunc) (int64, error) {
38 if tf == nil {
39 return io.Copy(w, r)
40 }
41 c := make(chan parser.Token)
42 e := make(chan error)
43 go handleTemplate(file, w, c, e)
44 var (
45 rw rwcount.Reader
46 p parser.Parser
47 )
48 if lr, ok := r.(*memio.LimitedBuffer); ok {
49 rw.Count = int64(len(*lr))
50 p = parser.New(parser.NewByteTokeniser(*lr))
51 } else {
52 rw.Reader = r
53 p = parser.New(parser.NewReaderTokeniser(&rw))
54 }
55 p.TokeniserState(tf)
56 for {
57 tk, err := p.GetToken()
58 if err != nil {
59 close(c)
60 <-e
61 return rw.Count, err
62 }
63 if tk.Type == parser.TokenDone {
64 close(c)
65 break
66 }
67 select {
68 case c <- tk:
69 case err := <-e:
70 return rw.Count, err
71 }
72 }
73 if err := <-e; err != nil {
74 return rw.Count, err
75 }
76 if rw.Err == io.EOF {
77 rw.Err = nil
78 }
79 return rw.Count, rw.Err
80 }
81