<s> """<STR_LIT>""" <EOL> from skbio . io import create_format , NewickFormatError <EOL> from skbio . tree import TreeNode <EOL> newick = create_format ( '<STR_LIT>' ) <EOL> @ newick . sniffer ( ) <EOL> def _newick_sniffer ( fh ) : <EOL> operators = set ( "<STR_LIT>" ) <EOL> empty = True <EOL> last_token = '<STR_LIT:U+002C>' <EOL> indent = <NUM_LIT:0> <EOL> try : <EOL> for token , _ in zip ( _tokenize_newick ( fh ) , range ( <NUM_LIT:100> ) ) : <EOL> if token not in operators : <EOL> pass <EOL> elif token == '<STR_LIT:U+002C>' and last_token != '<STR_LIT::>' and indent > <NUM_LIT:0> : <EOL> pass <EOL> elif token == '<STR_LIT::>' and last_token != '<STR_LIT::>' : <EOL> pass <EOL> elif token == '<STR_LIT:;>' and last_token != '<STR_LIT::>' and indent == <NUM_LIT:0> : <EOL> pass <EOL> elif token == '<STR_LIT:)>' and last_token != '<STR_LIT::>' : <EOL> indent -= <NUM_LIT:1> <EOL> elif token == '<STR_LIT:(>' and ( last_token == '<STR_LIT:(>' or last_token == '<STR_LIT:U+002C>' ) : <EOL> indent += <NUM_LIT:1> <EOL> else : <EOL> raise NewickFormatError ( ) <EOL> last_token = token <EOL> empty = False <EOL> except NewickFormatError : <EOL> return False , { } <EOL> return not empty , { } <EOL> @ newick . reader ( TreeNode ) <EOL> def _newick_to_tree_node ( fh , convert_underscores = True ) : <EOL> tree_stack = [ ] <EOL> current_depth = <NUM_LIT:0> <EOL> last_token = '<STR_LIT>' <EOL> next_is_distance = False <EOL> root = TreeNode ( ) <EOL> tree_stack . append ( ( root , current_depth ) ) <EOL> for token in _tokenize_newick ( fh , convert_underscores = convert_underscores ) : <EOL> if last_token not in '<STR_LIT>' : <EOL> if not next_is_distance : <EOL> tree_stack [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] . name = last_token if last_token else None <EOL> else : <EOL> next_is_distance = False <EOL> if token == '<STR_LIT::>' : <EOL> next_is_distance = True <EOL> elif last_token == '<STR_LIT::>' : <EOL> try : <EOL> tree_stack [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] . length = float ( token ) <EOL> except ValueError : <EOL> raise NewickFormatError ( "<STR_LIT>" <EOL> "<STR_LIT>" % token ) <EOL> elif token == '<STR_LIT:(>' : <EOL> current_depth += <NUM_LIT:1> <EOL> tree_stack . append ( ( TreeNode ( ) , current_depth ) ) <EOL> elif token == '<STR_LIT:U+002C>' : <EOL> tree_stack . append ( ( TreeNode ( ) , current_depth ) ) <EOL> elif token == '<STR_LIT:)>' : <EOL> if len ( tree_stack ) < <NUM_LIT:2> : <EOL> raise NewickFormatError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> children = [ ] <EOL> while current_depth == tree_stack [ - <NUM_LIT:1> ] [ <NUM_LIT:1> ] : <EOL> node , _ = tree_stack . pop ( ) <EOL> children . insert ( <NUM_LIT:0> , node ) <EOL> parent = tree_stack [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] <EOL> if parent . children : <EOL> raise NewickFormatError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> for child in children : <EOL> child . parent = parent <EOL> parent . children = children <EOL> current_depth -= <NUM_LIT:1> <EOL> elif token == '<STR_LIT:;>' : <EOL> if len ( tree_stack ) == <NUM_LIT:1> : <EOL> return root <EOL> break <EOL> last_token = token <EOL> raise NewickFormatError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> @ newick . writer ( TreeNode ) <EOL> def _tree_node_to_newick ( obj , fh ) : <EOL> operators = set ( "<STR_LIT>" ) <EOL> current_depth = <NUM_LIT:0> <EOL> nodes_left = [ ( obj , <NUM_LIT:0> ) ] <EOL> while len ( nodes_left ) > <NUM_LIT:0> : <EOL> entry = nodes_left . pop ( ) <EOL> node , node_depth = entry <EOL> if node . children and node_depth >= current_depth : <EOL> fh . write ( '<STR_LIT:(>' ) <EOL> nodes_left . append ( entry ) <EOL> nodes_left += ( ( child , node_depth + <NUM_LIT:1> ) for child in <EOL> reversed ( node . children ) ) <EOL> current_depth = node_depth + <NUM_LIT:1> <EOL> else : <EOL> if node_depth < current_depth : <EOL> fh . write ( '<STR_LIT:)>' ) <EOL> current_depth -= <NUM_LIT:1> <EOL> if node . name : <EOL> escaped = "<STR_LIT:%s>" % node . name . replace ( "<STR_LIT:'>" , "<STR_LIT>" ) <EOL> if any ( t in operators for t in node . name ) : <EOL> fh . write ( "<STR_LIT:'>" ) <EOL> fh . write ( escaped ) <EOL> fh . write ( "<STR_LIT:'>" ) <EOL> else : <EOL> fh . write ( escaped . replace ( "<STR_LIT:U+0020>" , "<STR_LIT:_>" ) ) <EOL> if node . length is not None : <EOL> fh . write ( '<STR_LIT::>' ) <EOL> fh . write ( "<STR_LIT:%s>" % node . length ) <EOL> if nodes_left and nodes_left [ - <NUM_LIT:1> ] [ <NUM_LIT:1> ] == current_depth : <EOL> fh . write ( '<STR_LIT:U+002C>' ) <EOL> fh . write ( '<STR_LIT>' ) <EOL> def _tokenize_newick ( fh , convert_underscores = True ) : <EOL> structure_tokens = set ( '<STR_LIT>' ) <EOL> not_escaped = True <EOL> label_start = False <EOL> last_non_ws_char = '<STR_LIT>' <EOL> last_char = '<STR_LIT>' <EOL> comment_depth = <NUM_LIT:0> <EOL> metadata_buffer = [ ] <EOL> for line in fh : <EOL> for character in line : <EOL> if character == "<STR_LIT:[>" and not_escaped : <EOL> if last_non_ws_char != "<STR_LIT:'>" or comment_depth == <NUM_LIT:0> : <EOL> comment_depth += <NUM_LIT:1> <EOL> if comment_depth > <NUM_LIT:0> : <EOL> if character == "<STR_LIT:]>" and last_non_ws_char != "<STR_LIT:'>" : <EOL> comment_depth -= <NUM_LIT:1> <EOL> last_non_ws_char = character <EOL> continue <EOL> if not_escaped and character in structure_tokens : <EOL> label_start = False <EOL> metadata = '<STR_LIT>' . join ( metadata_buffer ) <EOL> if last_non_ws_char == "<STR_LIT:'>" or not convert_underscores : <EOL> yield metadata <EOL> elif metadata : <EOL> yield metadata . replace ( '<STR_LIT:_>' , '<STR_LIT:U+0020>' ) <EOL> metadata_buffer = [ ] <EOL> yield character <EOL> elif character == "<STR_LIT:'>" : <EOL> not_escaped = not not_escaped <EOL> label_start = True <EOL> if last_non_ws_char == "<STR_LIT:'>" : <EOL> metadata_buffer . append ( character ) <EOL> last_non_ws_char = '<STR_LIT>' <EOL> last_char = '<STR_LIT>' <EOL> continue <EOL> elif not character . isspace ( ) or not not_escaped : <EOL> if label_start and last_char . isspace ( ) and not_escaped : <EOL> raise NewickFormatError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> metadata_buffer . append ( character ) <EOL> label_start = True <EOL> elif True : <EOL> last_char = character <EOL> continue <EOL> last_char = character <EOL> last_non_ws_char = character </s>
