beemovie.py 5.29 KB
Newer Older
Henke's avatar
Update    
Henke committed
1
from __future__ import print_function
Henke's avatar
Henke committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import argparse
from collections import namedtuple

TextPointer = namedtuple('TextPointer', 'index')

NO_EXCEPT = True
BEE_FILE = 'beemovie.txt'

def read_file(cache=[]):
    if cache:
        return cache
    with open(BEE_FILE, 'r') as f:
        lines = [x.strip() for x in f]
    non_empty_lines = [x for x in lines if x]
    for line in non_empty_lines:
        cache.extend(line.split())
    return cache

def beetext():
    return read_file()

def beeify(line, text_ptr, max_len, comment, inline_l, inline_r):
    '''Returns an updated line and a new text pointer.'''
    if len(line) > max_len and not NO_EXCEPT:
        raise Exception("You have one line that is too long: {}".format(line))
    if text_ptr.index >= len(beetext()):
        return line, text_ptr
    text = beetext()

    # Fix inline comments
    if inline_l:
        space_len = 0
        while space_len < len(line) and line[space_len] == ' ':
            space_len += 1
        space_len -= 1
        current = inline_l
        while len(current) + 1 + len(inline_r) + len(text[text_ptr.index]) <= space_len:
            current += ' {}'.format(text[text_ptr.index])
            text_ptr = TextPointer(text_ptr.index + 1)
            if text_ptr.index >= len(text):
Henke's avatar
Update    
Henke committed
42
                text_ptr = TextPointer(0)
Henke's avatar
Henke committed
43
44
45
46
47
48
49
50
51
52
53
54
55

        if current != inline_l:
            while len(current) + 1 + len(inline_r) < space_len:
                current += ' '
            current += ' {}'.format(inline_r)
            line = current + line[len(current):]

        if line.strip().endswith('\\'):
            # Use inline comments at end of line
            current = ' {}'.format(inline_l)
            while len(line) + len(current) + 1 + len(inline_r) + len(text[text_ptr.index]) <= max_len:
                current += ' {}'.format(text[text_ptr.index])
                text_ptr = TextPointer(text_ptr.index + 1)
Henke's avatar
Update    
Henke committed
56
57
                if text_ptr.index >= len(beetext()):
                    text_ptr = TextPointer(0)
Henke's avatar
Henke committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
            if current != inline_l:
                while len(line) + len(current) + 1 + len(inline_r) < max_len:
                    current += ' '
                current += ' {}'.format(inline_r)
                return '{}{}'.format(line, current), text_ptr

    # Fix end of line comments
    current = ''
    comment_len = len(' {}'.format(comment))
    while text_ptr.index < len(text) and \
          len(line) + comment_len + len(current) + len(text[text_ptr.index]) + 1 <= max_len:
        current += ' {}'.format(beetext()[text_ptr.index])
        text_ptr = TextPointer(text_ptr.index + 1)
        if text_ptr.index >= len(beetext()):
Henke's avatar
Update    
Henke committed
72
            text_ptr = TextPointer(0)
Henke's avatar
Henke committed
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

    if not current:
        return line, text_ptr

    # Left pad until right aligned
    while len('{} {}{}'.format(line, comment, current)) < max_len:
        line += ' '
    return '{} {}{}'.format(line, comment, current), text_ptr

def beeify_file(fname, max_len, comment, text_ptr, L, R):
    with open(fname, 'r') as f:
        lines = [x.rstrip() for x in f.readlines()]
    bee_lines = []
    for line in lines:
        bee, text_ptr = beeify(line, text_ptr, max_len, comment, L, R)
        bee_lines.append(bee)
    return bee_lines, text_ptr

def beeify_filename(fname):
Henke's avatar
Update    
Henke committed
92
93
94
    unbeed = fname.split('.')
    unbeed = unbeed[:-1] + ['bee'] + [unbeed[-1]]
    return '.'.join(unbeed)
Henke's avatar
Henke committed
95
96
97
98
99
100
101
102
103
104
105

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Create bee-ified source code')
    parser.add_argument('filename', nargs='+', help='Input files to apply the bee-ifier on')
    parser.add_argument('--print', dest='should_print', action='store_const',
                        const=True, default=False, help='Prints the resulting file')
    parser.add_argument('--width', type=int, default=80, help='width of each file line')
    parser.add_argument('--comment', type=str, default='//', help='comment string')
    parser.add_argument('--beesource', help='Specify source for bee movie script')
    parser.add_argument('--exceptions', action='store_const',
                        const=True, default=False, help='Raise exceptions for long lines')
Henke's avatar
Henke committed
106
107
    parser.add_argument('--overwrite', action='store_const',
                        const=True, default=False, help='Overwrite input files')
Henke's avatar
Henke committed
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    parser.add_argument('--comment-l', type=str, default='', dest='L',
                        help='Use this as left side of inline comment.')
    parser.add_argument('--comment-r', type=str, default='', dest='R',
                        help='Use this as right side of inline comment. (Both left and right needs to be set to work)')

    args = parser.parse_args()
    BEE_FILE = BEE_FILE or args.beesource
    NO_EXCEPT = not args.exceptions
    L, R = args.L, args.R
    text_ptr = TextPointer(0)
    if args.should_print:
        bee = []
        for fname in args.filename:
            line, text_ptr = beeify_file(fname, args.width, args.comment, text_ptr, L, R)
            bee.extend(line)
        for line in bee:
            print(line)
    else:
        for fname in args.filename:
Henke's avatar
Henke committed
127
128
129
            beefname = fname
            if not args.overwrite:
                beefname = beeify_filename(fname)
Henke's avatar
Henke committed
130
131
132
133
            lines, text_ptr = beeify_file(fname, args.width, args.comment, text_ptr, L, R)
            with open(beefname, 'w') as f:
                for line in lines:
                    print(line, file=f)