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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#!/usr/bin/env python3
# Apache License, Version 2.0
"""
Remap RST title levels
"""
def title_level_edit(fn, data_src, level_add):
# as defined by
# https://docs.python.org/devguide/documenting.html
#
# note: include levels not found in Python docs
# so we can bump up/down and still have a unique title char.
title_chars = (
'%', # not from python docs!
'#',
'*',
'=',
'-',
'^',
'"',
"'", # not from python docs!
)
title_levels = {ch: i for i, ch in enumerate(title_chars)}
def retitle(title, level_text, level):
level_text = title_chars[level] * len(level_text)
# print(title)
# print(level_text)
return title, level_text
lines = data_src.split("\n")
l_prev = None
l_prev_prev = None
for i in range(len(lines) - 1):
l = lines[i]
l = l.rstrip()
# expect a blank line after the title
if not lines[i + 1].rstrip():
is_title = False
if (l_prev_prev is not None):
# 3 line title?
if l_prev and l and (l == l_prev_prev):
level = title_levels.get(l[0], -1)
if level != -1 and l.count(l[0]) == len(l):
# adjust the current title level
level += level_add
title_new, level_text_new = retitle(l_prev, l, level)
lines[i - 2] = lines[i] = level_text_new
lines[i - 1] = title_new
is_title = True
if (l_prev is not None) and not is_title:
# 2 line title?
if l_prev and l and (len(l) == len(l_prev)):
level = title_levels.get(l[0], -1)
if level != -1 and l.count(l[0]) == len(l):
# adjust the current title level
level += level_add
title_new, level_text_new = retitle(l_prev, l, level)
lines[i] = level_text_new
lines[i - 1] = title_new
is_title = True
l_prev_prev = l_prev
l_prev = l
data_dst = "\n".join(lines)
return data_dst
def create_argparse():
import argparse
usage_text = __doc__
parser = argparse.ArgumentParser(
prog="bam",
description=usage_text,
)
parser.add_argument(
dest="paths", nargs="*",
help="Path(s) to operate on",
)
parser.add_argument(
"-l", "--level", dest="level", metavar='LEVEL', required=True,
default=1, type=int,
help="The level to add/remove from the titles",
)
return parser
def main(argv=None):
import sys
import os
if argv is None:
argv = sys.argv[1:]
parser = create_argparse()
args = parser.parse_args(argv)
for f in args.paths:
if os.path.exists(f):
with open(f, 'r', encoding='utf-8') as f_handle:
data_src = f_handle.read()
data_dst = title_level_edit(f, data_src, args.level)
with open(f, 'w', encoding='utf-8') as f_handle:
f_handle.write(data_dst)
else:
print("Path not found! $r" % f)
if __name__ == "__main__":
main()
|