handle indented snippets

This commit is contained in:
Zander Thannhauser 2025-03-29 19:04:30 -05:00
parent 8f5ad8b22f
commit 89bb34256e

53
zpp
View file

@ -51,8 +51,6 @@ def main(args):
# So I think it makes the most sense to break the input text by "/*/"?
# and then depending on whether a snippet has a newline, we handle it
# differently?
# The trouble with that appoarch, is that we won't preserve the indentation.
# I'm not sure that really matters.
divisions = entire_input.split("/*/")
@ -64,13 +62,58 @@ def main(args):
if passthrough:
ostream.write(division);
elif "\n" in division:
# this would be a multi-line snippet, so we'll run the source
# altogether and capture the output:
# This would be a multi-line snippet, so we'll run the source
# altogether and capture the output.
# Python is funny about indentation, so we will have to strip off
# the initial left indentation of each of the lines of the snippet.
# So step 1 is figuring out how much indentation we need to remove.
# We'll look at the first line for that.
# bonus points if we can support tabs too!
lines = division.split('\n');
first_nonempty_line = None;
# let's find the first non-empty line:
for line in lines:
if line.strip():
first_nonempty_line = line;
break;
if first_nonempty_line is None:
print(f"zpp: error! empty snippet!");
return 1;
# and just build up the string the whitespace:
indentation = '';
for c in first_nonempty_line:
if c.isspace():
indentation += c
else:
break;
# now that we know how many spaces to eliminate, let's go through
# each line and remove them. lines of just whitespace can be
# passed through with getting processed.
source = "";
for line in lines:
if not line.strip():
source += line + '\n';
elif line.startswith(indentation):
source += line[len(indentation):] + '\n';
else:
print(f"zpp: error! mixed indentation in snippet!");
return 1;
real_stdout = sys.stdout
sys.stdout = captured_stdout = io.StringIO()
eval(compile(division, "<zog-snippet>", "exec"), snippet_globals);
eval(compile(source, "<zog-snippet>", "exec"), snippet_globals);
sys.stdout = real_stdout