Created
September 19, 2014 08:44
-
-
Save mtholder/3f88a6636acb70731369 to your computer and use it in GitHub Desktop.
print a word as it should appear if it is a node label (including tip label) in a newick tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| import sys | |
| import os | |
| import re | |
| _SCRIPT_NAME = os.path.split(sys.argv[0])[-1] | |
| _FORBIDDEN = re.compile(r'[^- 0-9a-zA-Z`~@#$%^&*()_+={}|\\\[\]:;"\'<,>.?/]') | |
| _NEEDS_QU_PUNC_STR = r'[\[\]():,;]' | |
| _NEEDS_QUOTES_PATTERN = re.compile(r'(\s|' + _NEEDS_QU_PUNC_STR + ')') | |
| _NEEDS_QUOTES_PUNC_PATTERN = re.compile(_NEEDS_QU_PUNC_STR) | |
| _SINGLE_QUOTE = "'" | |
| _TWO_QUOTES = "''" | |
| def print_quoted(word): | |
| # reject labels any label with a character other than: | |
| # spaces, Roman alphabet letters, and US keyboard punctuation | |
| if _FORBIDDEN.search(word): | |
| msg = 'The input word "' + word + '" a forbidden character!\n' | |
| sys.stderr.write(_SCRIPT_NAME + ': ' + msg) | |
| return False | |
| if _SINGLE_QUOTE in word: | |
| # in newick and NEXUS a label with ' has to have | |
| # ' on the outside and change every ' to '' (two single quotes) | |
| split_on_quote = word.split(_SINGLE_QUOTE) | |
| doubled_single_quotes = _TWO_QUOTES.join(split_on_quote) | |
| print _SINGLE_QUOTE + doubled_single_quotes + _SINGLE_QUOTE | |
| elif _NEEDS_QUOTES_PATTERN.search(word): | |
| if not _NEEDS_QUOTES_PUNC_PATTERN.search(word): | |
| # space is the only special char. | |
| # we can use the _ for space trick that users prefer... | |
| print '_'.join(word.split(' ')) | |
| else: | |
| print _SINGLE_QUOTE + word + _SINGLE_QUOTE | |
| else: | |
| print word | |
| return True | |
| if __name__ == '__main__': | |
| if len(sys.argv) > 1: | |
| inp = sys.argv[1:] | |
| strip_newline = False | |
| else: | |
| inp = iter(sys.stdin) | |
| strip_newline = True | |
| n_failed = 0 | |
| for word in inp: | |
| if strip_newline: | |
| word = word[:-1] | |
| if not print_quoted(word): | |
| n_failed += 1 | |
| if n_failed > 0: | |
| sys.stderr.write('{s}: {f} words rejected.\n'.format(s=_SCRIPT_NAME, f=n_failed)) | |
| sys.exit(1) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment