Skip to content

Instantly share code, notes, and snippets.

@Fortyseven
Created July 22, 2025 13:42
Show Gist options
  • Save Fortyseven/4c160da46c2f10f2e685665159a3e5cf to your computer and use it in GitHub Desktop.
Save Fortyseven/4c160da46c2f10f2e685665159a3e5cf to your computer and use it in GitHub Desktop.
Translate Python to Tabloid
# https://tabloid.vercel.app/
import ast
import sys
import os
# Mapping for operators
BINOP_MAP = {
ast.Add: 'PLUS',
ast.Sub: 'MINUS',
ast.Mult: 'TIMES',
ast.Div: 'DIVIDED BY',
ast.Mod: 'MODULO',
}
BOOLOP_MAP = {
ast.And: 'AND',
ast.Or: 'OR',
}
CMPOP_MAP = {
ast.Eq: 'IS ACTUALLY',
ast.Gt: 'BEATS',
ast.Lt: 'SMALLER THAN',
}
BOOL_LIT = {True: 'TOTALLY RIGHT', False: 'COMPLETELY WRONG'}
def tab_expr(node):
if isinstance(node, ast.BinOp):
return f"{tab_expr(node.left)} {BINOP_MAP[type(node.op)]} {tab_expr(node.right)}"
elif isinstance(node, ast.BoolOp):
op = BOOLOP_MAP[type(node.op)]
return f" {op} ".join(tab_expr(v) for v in node.values)
elif isinstance(node, ast.Compare):
left = tab_expr(node.left)
# Only support single comparator for now
op = CMPOP_MAP[type(node.ops[0])]
right = tab_expr(node.comparators[0])
return f"{left} {op} {right}"
elif isinstance(node, ast.Call):
# Only support simple function calls
func = tab_expr(node.func)
args = ', '.join(tab_expr(a) for a in node.args)
return f"{func} OF {args}" if args else f"{func} OF"
elif isinstance(node, ast.Name):
return node.id
elif isinstance(node, ast.Constant):
if isinstance(node.value, bool):
return BOOL_LIT[node.value]
elif isinstance(node.value, str):
return f"'{node.value}'"
else:
return str(node.value)
elif isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
return f"MINUS {tab_expr(node.operand)}"
else:
return '<UNSUPPORTED_EXPR>'
def tab_stmt(node, indent=0):
IND = ' ' * indent
lines = []
if isinstance(node, ast.Assign):
# Only support single target
target = node.targets[0]
if isinstance(target, ast.Name):
lines.append(f"{IND}EXPERTS CLAIM {target.id} TO BE {tab_expr(node.value)}")
elif isinstance(node, ast.Expr):
# Print statement or function call
if isinstance(node.value, ast.Call) and isinstance(node.value.func, ast.Name) and node.value.func.id == 'print':
arg = node.value.args[0] if node.value.args else ast.Constant(value='')
lines.append(f"{IND}YOU WON'T WANT TO MISS {tab_expr(arg)}")
else:
lines.append(f"{IND}{tab_expr(node.value)}")
elif isinstance(node, ast.FunctionDef):
args = ', '.join(a.arg for a in node.args.args)
lines.append(f"{IND}DISCOVER HOW TO {node.name} WITH {args}")
lines.append(f"{IND}RUMOR HAS IT")
for stmt in node.body:
lines.extend(tab_stmt(stmt, indent+1))
lines.append(f"{IND}END OF STORY")
elif isinstance(node, ast.If):
lines.append(f"{IND}WHAT IF {tab_expr(node.test)}")
for stmt in node.body:
lines.extend(tab_stmt(stmt, indent+1))
if node.orelse:
lines.append(f"{IND}LIES!")
for stmt in node.orelse:
lines.extend(tab_stmt(stmt, indent+1))
elif isinstance(node, ast.Return):
lines.append(f"{IND}SHOCKING DEVELOPMENT {tab_expr(node.value)}")
else:
lines.append(f"{IND}# <UNSUPPORTED_STMT>")
return lines
def py2tab(source):
tree = ast.parse(source)
lines = []
for node in tree.body:
lines.extend(tab_stmt(node))
return lines
def main():
if len(sys.argv) < 2:
print("Usage: python py2tab.py input.py")
sys.exit(1)
pyfile = sys.argv[1]
if not pyfile.endswith('.py'):
print("Input file must be a .py file")
sys.exit(1)
with open(pyfile) as f:
source = f.read()
tab_lines = py2tab(source)
# Add end of program
tab_lines.append('PLEASE LIKE AND SUBSCRIBE')
for line in tab_lines:
print(line)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment