func PassToken(str string) func(*Pipe) {
	return Pass(func(ti Token) bool {
		return ti.Str == str
	})
}
PassToken is like Pass, passing all tokens whose string content is equal to
the given string.
package goprep
import (
	"bytes"
	"fmt"
	"go/parser"
	"go/printer"
	"go/scanner"
	"go/token"
	"io"
	"io/ioutil"
)
type Token struct {
	Pos   token.Position
	Token token.Token
	Str   string
}
type Pipe struct {
	Input  chan Token
	Output chan string
	Sync   chan interface{}
}
func PipeInit(iReader io.Reader) *Pipe {
	input := make(chan Token)
	output := make(chan string)
	sync := make(chan interface{})
	p := &Pipe{input, output, sync}
	src, err := ioutil.ReadAll(iReader)
	if err != nil {
		panic(err)
	}
	fset := token.NewFileSet()
	file := fset.AddFile("<stdin>", fset.Base(), len(src))
	s := scanner.Scanner{}
	s.Init(file, src, nil, scanner.ScanComments)
	go func() {
		pos, tok, str := s.Scan()
		for tok != token.EOF {
			if len(str) == 0 { str = tok.String() }
			if tok == token.COMMENT {
				str = str + "\n"
			}
			input <- Token{fset.Position(pos), tok, str}
			<-sync  
			pos, tok, str = s.Scan()
		}
		close(input)
	}()
	return p
}
func PipeEnd(p *Pipe, oWriter io.Writer) {
	go func() {
		for _ = range p.Input {
			panic("Leftovers")
		}
		close(p.Output)
		close(p.Sync)
	}()
	outbuf := new(bytes.Buffer)
	output := p.Output
	for tok := range output {
		fmt.Fprintf(outbuf, " %s", tok)
	}
	fset := token.NewFileSet()
	file, err := parser.ParseFile(
		fset, "<stdin>", outbuf, parser.ParseComments)
	if err != nil {
		panic(err)
	}
	printer.Fprint(oWriter, fset, file)
}
func True(Token) bool { return true }
func False(Token) bool { return false }
func Lines(pipeline *Pipe) {
	tIn := pipeline.Input
	tOut := make(chan Token)
	out := pipeline.Output
	isync := pipeline.Sync
	osync := make(chan interface{})
	fname := ""
	lno := 0
	pipeline.Input = tOut
	pipeline.Sync = osync
	go func() {
		for tok := range tIn {
			fname = tok.Pos.Filename
			lno = tok.Pos.Line
			tOut <- tok
			<-osync  
			if tok.Str == "\n" {
				ld := fmt.Sprintf("//line %s:%d\n", fname, lno)
				out <- ld
			}
			isync <- nil
		}
		close(tOut)
	}()
}
func Ignore(f func(Token) bool) func(*Pipe) {
	return func(p *Pipe) {
		tOut := make(chan Token)
		tIn := p.Input
		sync := p.Sync
		go func() {
			for tok := range tIn {
				if !f(tok) {
					tOut <- tok
				} else {
					sync <- nil
				}
			}
			close(tOut)
		}()
		p.Input = tOut
	}
}
func IgnoreToken(str string) func(*Pipe) {
	return Ignore(func(ti Token) bool {
		return ti.Str == str
	})
}
func IgnoreType(tok token.Token) func(*Pipe) {
	return Ignore(func(ti Token) bool {
		return ti.Token == tok
	})
}
func Pass(f func(Token) bool) func(*Pipe) {
	return func(p *Pipe) {
		tOut := make(chan Token)
		tIn := p.Input
		out := p.Output
		sync := p.Sync
		go func() {
			for tok := range tIn {
				if f(tok) {
					out <- tok.Str
					sync <- nil
				} else {
					tOut <- tok
				}
			}
			close(tOut)
		}()
		p.Input = tOut
	}
}