xipd

programming language for audio processing that compiles to PureData
git clone https://git.ce9e.org/xipd.git

commit
aef92e47307c59830001391eb97b04aebd707436
parent
dffceeaf3b25877e7cb1d11675ab6ddeee5e6164
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2022-08-26 10:13
add autoformat

Diffstat

A xipd/format.py 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1 files changed, 65 insertions, 0 deletions


diff --git a/xipd/format.py b/xipd/format.py

@@ -0,0 +1,65 @@
   -1     1 import re
   -1     2 import sys
   -1     3 import subprocess
   -1     4 
   -1     5 DOT_CMD = 'dot'
   -1     6 
   -1     7 
   -1     8 def pd2dot(pd):
   -1     9 	connections = []
   -1    10 	index = 0
   -1    11 	out = ['digraph _ {']
   -1    12 	for line in pd.splitlines():
   -1    13 		if line.startswith('#X connect'):
   -1    14 			parts = line.split()
   -1    15 			a = parts[2]
   -1    16 			b = parts[4]
   -1    17 			connections.append((a, b))
   -1    18 			out.append(f'  {b} -> {a};')
   -1    19 		elif line.startswith('#X obj') or line.startswith('#X msg'):
   -1    20 			out.append(f'  {index};')
   -1    21 			index += 1
   -1    22 	out.append('}')
   -1    23 	return '\n'.join(out)
   -1    24 
   -1    25 
   -1    26 def parse_dot(dot):
   -1    27 	positions = {}
   -1    28 	dot = dot.replace(',\n', ', ')
   -1    29 	for line in dot.splitlines():
   -1    30 		m = re.match(r'\s*([0-9]+).*pos="([0-9]+),([0-9]+)"', line)
   -1    31 		if m:
   -1    32 			i = int(m.group(1))
   -1    33 			x = float(m.group(2))
   -1    34 			y = float(m.group(3))
   -1    35 			positions[i] = x, y
   -1    36 	return positions
   -1    37 
   -1    38 
   -1    39 def apply_positions(pd, positions):
   -1    40 	index = 0
   -1    41 	lines = []
   -1    42 	for line in pd.splitlines():
   -1    43 		if line.startswith('#X obj') or line.startswith('#X msg'):
   -1    44 			x, y = positions[index]
   -1    45 			parts = line.split()
   -1    46 			parts[2] = str(x)
   -1    47 			parts[3] = str(y)
   -1    48 			lines.append(' '.join(parts))
   -1    49 			index += 1
   -1    50 		else:
   -1    51 			lines.append(line)
   -1    52 	return ''.join(l + '\r\n' for l in lines)
   -1    53 
   -1    54 
   -1    55 def autoformat(pd):
   -1    56 	dot = pd2dot(pd)
   -1    57 	p = subprocess.run(DOT_CMD, input=dot, capture_output=True, text=True)
   -1    58 	positions = parse_dot(p.stdout)
   -1    59 	return apply_positions(pd, positions)
   -1    60 
   -1    61 
   -1    62 if __name__ == '__main__':
   -1    63 	with open(sys.argv[1]) as fh:
   -1    64 		pd = fh.read()
   -1    65 	print(autoformat(pd), end='')