code: func NewPattern(tokens []*Token) Pattern {
  	// if we have no tokens there is no pattern
  	if len(tokens) == 0 {
  		return nil
  	}
  
  	// extract the pattern position from first token
  	_position := tokens[0].Position
  	_string := tokenset(tokens).String()
  
  	// is this a negated pattern?
  	_negated := false
  	if tokens[0].Type == NEGATION {
  		_negated = true
  		tokens = tokens[1:]
  	}
  
  	// is this pattern anchored to the start of the path?
  	_anchored := false
  	if tokens[0].Type == SEPARATOR {
  		_anchored = true
  		tokens = tokens[1:]
  	}
  
  	// is this pattern for directories only?
  	_directory := false
  	_last := len(tokens) - 1
  	if tokens[_last].Type == SEPARATOR {
  		_directory = true
  		tokens = tokens[:_last]
  	}
  
  	// build the pattern expression
  	_fnmatch := tokenset(tokens).String()
  	_pattern := &pattern{
  		_negated:   _negated,
  		_anchored:  _anchored,
  		_position:  _position,
  		_directory: _directory,
  		_string:    _string,
  		_fnmatch:   _fnmatch,
  	}
  	return _pattern.compile(tokens)
  }
docs: // NewPattern returns a Pattern from the ordered slice of Tokens. The tokens are
  // assumed to represent a well-formed .gitignore pattern. A Pattern may be
  // negated, anchored to the start of the path (relative to the base directory
  // of tie containing .gitignore), or match directories only.