basename, ext = os.path.splitext(files[0])
out_file = basename + ".compiled" + ext
- with open(out_file, mode='w') as out:
- variables = {}
- imported_files = []
-
+ variables = {}
+ imported_files = []
+ def parse(f):
+ nonlocal variables, imported_files
not_just_variable_declarations = False
+ in_variable_declarations = False
+ in_comment = False
+ for line in f:
+ # In comment and the comment is not ending yet, ignore
+ if in_comment:
+ if comment_end_rx.match(line):
+ in_comment = False
+ continue
+
+ # Import statement: add the file to additionally processed files
+ # unless it's disabled
+ match = import_rx.match(line)
+ if match:
+ if process_imports:
+ imported_files += [match['file']]
+ continue
+
+ # Variable use, replace with actual value
+ # TODO: more variables on the same line?
+ match = variable_use_rx.match(line)
+ if match and match['key'] in variables:
+ out.write(match['before'])
+ out.write(variables[match['key']])
+ out.write(match['after'])
+ out.write("\n")
+ continue
+
+ # Opening brace of variable declaration block
+ match = opening_brace_rx.match(line)
+ if match:
+ in_variable_declarations = True
+ continue
+
+ # Variable declaration
+ match = variable_declaration_rx.match(line)
+ if match and in_variable_declarations:
+ variables[match['key']] = match['value']
+ continue
+
+ # Comment or empty line, ignore
+ if comment_rx.match(line):
+ continue
+
+ # Comment start line, ignore this and the next lines
+ if comment_start_rx.match(line):
+ in_comment = True
+ continue
+
+ # Closing brace of variable declaration block. If it was not just
+ # variable declarations, put the closing brace to the output as
+ # well.
+ match = closing_brace_rx.match(line)
+ if match and in_variable_declarations:
+ if not_just_variable_declarations: out.write("}\n")
+ in_variable_declarations = False
+ continue
+
+ # If inside variable declaration block, include also the opening
+ # brace and remeber to put the closing brace there as well
+ if in_variable_declarations:
+ out.write(":root {\n")
+ not_just_variable_declarations = True
+
+ # Something else, copy verbatim to the output. Strip the trailing
+ # comment, if there, to save some bytes.
+ if line.rstrip().endswith('*/'):
+ out.write(line[:line.rindex('/*')].rstrip() + '\n')
+ else:
+ out.write(line)
+ with open(out_file, mode='w') as out:
# Put a helper comment and a license blob on top
out.write("""/* Generated using `./postprocess.py {}`. Do not edit. */
""".format(' '.join(sys.argv[1:])))
# Parse the top-level file
- with open(files[0]) as f:
- in_variable_declarations = False
- in_comment = False
- for line in f:
- # In comment and the comment is not ending yet, ignore
- if in_comment:
- if comment_end_rx.match(line):
- in_comment = False
- continue
-
- # Import statement: add the file to additionally processed
- # files unless it's disabled
- match = import_rx.match(line)
- if match:
- if process_imports:
- imported_files += [match['file']]
- continue
-
- # Opening brace of variable declaration block
- match = opening_brace_rx.match(line)
- if match:
- in_variable_declarations = True
- continue
-
- # Variable declaration
- match = variable_declaration_rx.match(line)
- if match and in_variable_declarations:
- variables[match['key']] = match['value']
- continue
-
- # Comment or empty line, ignore
- if comment_rx.match(line):
- continue
-
- # Comment start line, ignore this and the next lines
- if comment_start_rx.match(line):
- in_comment = True
- continue
-
- # Closing brace of variable declaration block. If it was not
- # just variable declarations, put the closing brace to the
- # output as well.
- match = closing_brace_rx.match(line)
- if match and in_variable_declarations:
- if not_just_variable_declarations: out.write("}\n")
- in_variable_declarations = False
- continue
-
- # Something else, copy verbatim to the output. If inside
- # variable declaration block, include also the opening brace
- # and remeber to put the closing brace there as well
- if in_variable_declarations:
- out.write(":root {\n")
- not_just_variable_declarations = True
-
- # Strip the trailing comment, if there, to save some bytes
- if line.rstrip().endswith('*/'):
- out.write(line[:line.rindex('/*')])
- else:
- out.write(line)
-
- # Now open the imported files and replace variables
+ with open(files[0]) as f: parse(f)
+
+ # Now open the imported files and parse them as well. Not doing any
+ # recursive parsing.
for file in imported_files + files[1:]:
out.write('\n')
- with open(file) as f:
- in_comment = False
- for line in f:
- # In comment and the comment is not ending yet, ignore
- if in_comment:
- if comment_end_rx.match(line):
- in_comment = False
- continue
-
- # Variable use, replace with actual value
- # TODO: more variables on the same line?
- match = variable_use_rx.match(line)
- if match and match['key'] in variables:
- out.write(match['before'])
- out.write(variables[match['key']])
- out.write(match['after'])
- out.write("\n")
- continue
-
- # Comment or empty line, ignore
- if comment_rx.match(line):
- continue
-
- # Comment start line, ignore this and the next lines
- if comment_start_rx.match(line):
- in_comment = True
- continue
-
- # Something else, copy verbatim to the output. Strip the
- # trailing comment, if there, to save some bytes
- if line.rstrip().endswith('*/'):
- out.write(line[:line.rindex('/*')].rstrip() + '\n')
- else:
- out.write(line)
+ with open(file) as f: parse(f)
return 0