code: func (p *Printer) Print(w io.Writer, node Node) error {
  	p.reset()
  
  	// TODO: consider adding a raw mode to skip the tab writer, much like in
  	// go/printer.
  	twmode := tabwriter.DiscardEmptyColumns | tabwriter.StripEscape
  	tabwidth := 8
  	if p.indentSpaces == 0 {
  		// indenting with tabs
  		twmode |= tabwriter.TabIndent
  	} else {
  		// indenting with spaces
  		tabwidth = int(p.indentSpaces)
  	}
  	p.tabWriter.Init(w, 0, tabwidth, 1, ' ', twmode)
  	w = p.tabWriter
  
  	p.bufWriter.Reset(w)
  	switch x := node.(type) {
  	case *File:
  		p.stmtList(x.Stmts, x.Last)
  		p.newline(x.End())
  	case *Stmt:
  		p.stmtList([]*Stmt{x}, nil)
  	case Command:
  		p.line = x.Pos().Line()
  		p.command(x, nil)
  	case *Word:
  		p.word(x)
  	case WordPart:
  		p.wordPart(x, nil)
  	default:
  		return fmt.Errorf("unsupported node type: %T", x)
  	}
  	p.flushHeredocs()
  	p.flushComments()
  
  	// flush the writers
  	if err := p.bufWriter.Flush(); err != nil {
  		return err
  	}
  	if tw, _ := w.(*tabwriter.Writer); tw != nil {
  		if err := tw.Flush(); err != nil {
  			return err
  		}
  	}
  	return nil
  }
docs: // Print "pretty-prints" the given syntax tree node to the given writer. Writes
  // to w are buffered.
  //
  // The node types supported at the moment are *File, *Stmt, *Word, any Command
  // node, and any WordPart node. A trailing newline will only be printed when a
  // *File is used.