You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.7 KiB

  1. #!/usr/bin/python
  2. import re
  3. import argparse
  4. import functools
  5. leading_whitespace = re.compile(r'^( +)(?! )')
  6. #@functools.lru_cache(maxsize=None)
  7. def get_whitespaces_re(line):
  8. return leading_whitespace.match(line)
  9. def get_indent_frequency(lines):
  10. lens = sorted(match.span()[1] for match in filter(bool,map(get_whitespaces_re,lines)))
  11. freq = {}
  12. for i in range(len(lens)-1):
  13. p = lens[i]
  14. n = lens[i+1]
  15. diff = n - p
  16. if diff > 0:
  17. new_val = freq.get(diff,0) + 1
  18. freq[diff] = new_val
  19. return freq
  20. def get_best_canitdate(lines):
  21. freqs = get_indent_frequency(lines)
  22. if freqs:
  23. return sorted(freqs.keys(),key = lambda k: freqs[k],reverse=True)[0]
  24. def change_all(text,new_indent):
  25. lines = text.split('\n')
  26. i = get_best_canitdate(lines)
  27. for row,line in enumerate(lines):
  28. prev_whitespaces = get_whitespaces_re(line)
  29. if prev_whitespaces is not None:
  30. prev_len = prev_whitespaces.span()[1]
  31. n,remaining = divmod(prev_len,i)
  32. if remaining*2 >= i:
  33. n += 1
  34. stripped = line.lstrip(' ')
  35. lines[row] = ' '*(new_indent*n) + stripped
  36. return '\n'.join(lines)
  37. if __name__ == "__main__":
  38. parser = argparse.ArgumentParser()
  39. parser.add_argument('-o',help='output file')
  40. parser.add_argument('file')
  41. parser.add_argument('indent',type=int)
  42. args = parser.parse_args()
  43. with open(args.file) as file:
  44. text = file.read()
  45. new = change_all(text,args.indent)
  46. if args.o:
  47. with open(args.o,'w') as file:
  48. file.write(new)
  49. else:
  50. with open(args.file,'w') as file:
  51. file.write(new)