-
Notifications
You must be signed in to change notification settings - Fork 34
/
someml-indent
executable file
·72 lines (57 loc) · 2.01 KB
/
someml-indent
1
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/env python3
import os, sys, io, re
p_err = lambda *a,**k: print(*a, file=sys.stderr, **k) or 1
def parse_tags(src):
'Returns "content" list of strings or (tag, attrs, content) tuples.'
dst = list()
while True:
m = re.search(
r'^(?P<pre>.*?)<\s*(?P<tag>[^\s>]+)\s*(?:\s(?P<attrs>[^>]+))?>'
r'(?P<content>.*?)' r'</\s*(?P=tag)\s*>', src, re.DOTALL )
if not m:
if src.strip(): dst.append(src)
break
src = src[m.end():]
pre, tag, attrs, c = m.groups()
if c:
if re.search(fr'<\s*{tag}\s*(?:\s[^>]+)?>', c):
p_err(f'WARNING: nested <{tag}> tags were matched incorrectly')
c = parse_tags(c)
if pre.strip(): dst.append(pre)
dst.append((tag, attrs, c))
return dst
def print_tags(src, dst, indent, pre=None, path=()):
if not src: return
inline = len(src) == 1
if pre is None: pre2 = ''
else: pre2 = (pre + indent) if not inline else pre
for n, v in enumerate(src):
if not inline: dst.write('\n' + pre2)
if isinstance(v, str):
dst.write(v.strip())
continue
tag, attrs, c = v
attrs = f' {attrs}' if attrs else ''
dst.write(f'<{tag}{attrs}>')
if c: print_tags(c, dst, indent, pre2, path=path+(f'{tag}.{n}',))
dst.write(f'</{tag}>')
if not inline: dst.write('\n' + (pre or ''))
if pre is None: dst.write('\n')
def main(args=None):
import argparse
parser = argparse.ArgumentParser(
description='Insert newlines into XML-ish thing, without really'
' validating or messing it up otherwise, except for added/stripped spaces.'
' Input - stdin, output - stdout.')
parser.add_argument('-i', '--indent-spaces',
type=int, default=2, metavar='num',
help='Number of spaces to use for a level indent, -1 = use tabs (default: %(default)s).')
opts = parser.parse_args(sys.argv[1:] if args is None else args)
src = sys.stdin.read()
src, dst = parse_tags(src), io.StringIO()
# exit(print(src))
indent = opts.indent_spaces
indent = (' '*indent) if indent >= 0 else '\t'
print_tags(src, dst, indent)
print(dst.getvalue().strip())
if __name__ == '__main__': sys.exit(main())