beemovie.py 5.08 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

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')
    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:
            beefname = beeify_filename(fname)
            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)