Return string of contents of parse_tree folded according to RFC rules.
(parse_tree, *, policy)
| 2838 | |
| 2839 | |
| 2840 | def _refold_parse_tree(parse_tree, *, policy): |
| 2841 | """Return string of contents of parse_tree folded according to RFC rules. |
| 2842 | |
| 2843 | """ |
| 2844 | # max_line_length 0/None means no limit, ie: infinitely long. |
| 2845 | maxlen = policy.max_line_length or sys.maxsize |
| 2846 | encoding = 'utf-8' if policy.utf8 else 'us-ascii' |
| 2847 | lines = [''] # Folded lines to be output |
| 2848 | last_word_is_ew = False |
| 2849 | last_ew = None # if there is an encoded word in the last line of lines, |
| 2850 | # points to the encoded word's first character |
| 2851 | last_charset = None |
| 2852 | wrap_as_ew_blocked = 0 |
| 2853 | want_encoding = False # This is set to True if we need to encode this part |
| 2854 | end_ew_not_allowed = Terminal('', 'wrap_as_ew_blocked') |
| 2855 | parts = list(parse_tree) |
| 2856 | while parts: |
| 2857 | part = parts.pop(0) |
| 2858 | if part is end_ew_not_allowed: |
| 2859 | wrap_as_ew_blocked -= 1 |
| 2860 | continue |
| 2861 | tstr = str(part) |
| 2862 | if not want_encoding: |
| 2863 | if part.token_type in ('ptext', 'vtext'): |
| 2864 | # Encode if tstr contains special characters. |
| 2865 | want_encoding = not SPECIALSNL.isdisjoint(tstr) |
| 2866 | else: |
| 2867 | # Encode if tstr contains newlines. |
| 2868 | want_encoding = not NLSET.isdisjoint(tstr) |
| 2869 | try: |
| 2870 | tstr.encode(encoding) |
| 2871 | charset = encoding |
| 2872 | except UnicodeEncodeError: |
| 2873 | if any(isinstance(x, errors.UndecodableBytesDefect) |
| 2874 | for x in part.all_defects): |
| 2875 | charset = 'unknown-8bit' |
| 2876 | else: |
| 2877 | # If policy.utf8 is false this should really be taken from a |
| 2878 | # 'charset' property on the policy. |
| 2879 | charset = 'utf-8' |
| 2880 | want_encoding = True |
| 2881 | |
| 2882 | if part.token_type == 'mime-parameters': |
| 2883 | # Mime parameter folding (using RFC2231) is extra special. |
| 2884 | _fold_mime_parameters(part, lines, maxlen, encoding) |
| 2885 | last_word_is_ew = False |
| 2886 | continue |
| 2887 | |
| 2888 | if want_encoding and not wrap_as_ew_blocked: |
| 2889 | if not part.as_ew_allowed: |
| 2890 | want_encoding = False |
| 2891 | last_ew = None |
| 2892 | if part.syntactic_break: |
| 2893 | encoded_part = part.fold(policy=policy)[:-len(policy.linesep)] |
| 2894 | if policy.linesep not in encoded_part: |
| 2895 | # It fits on a single line |
| 2896 | if len(encoded_part) > maxlen - len(lines[-1]): |
| 2897 | # But not on this one, so start a new one. |
no test coverage detected
searching dependent graphs…