Skip to content

Instantly share code, notes, and snippets.

@helenst
Forked from taldcroft/header_chars.py
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save helenst/18f403584a0e7edb3c0e to your computer and use it in GitHub Desktop.
Save helenst/18f403584a0e7edb3c0e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
"""
Find the sets of characters used in RST section headers,
and replace with a standard sequcne
For input like
::
##########
header
##########
Section
********
Subsection
===========
Section 2
**********
and HEADER_CHAR_LEVELS = '*=-^"+:~'
this should produce
::
**********
header
**********
Section
========
Subsection
-----------
Section 2
==========
It also checks that the ordering is valid.
Usage::
% find . -name "*.rst" | xargs ./replace_header_chars.py
"""
import re
import shutil
import sys
import tempfile
HEADER_CHAR_LEVELS = '*=-^"+:~'
def replace_header_chars(filename):
header_chars = ''
level = -1
rx = re.compile(r'^(\S)\1{3,}\s*$')
with open(filename, 'r') as infile, tempfile.NamedTemporaryFile(suffix='.rst', delete=False) as outfile:
for i, line in enumerate(infile):
match = rx.match(line)
if match:
char = match.group(1)
if char in header_chars:
# Existing header char: go back out to that level
new_level = header_chars.index(char)
if new_level > level + 1:
# doc tries to jump up too many levels
raise ValueError(
'ERROR misorder new_level={} level={} '
'char={} header_chars={} on line {}'.format(
new_level, level, char, header_chars, i))
else:
level = new_level
print 's/{}/{}/'.format(char, HEADER_CHAR_LEVELS[level])
else:
# New header char - create a deeper level
if level == len(header_chars) - 1:
header_chars += char
level += 1
print 's/{}/{}/'.format(char, HEADER_CHAR_LEVELS[level])
else:
# we're trying to create a new level, but we're not at the current deepest level
raise ValueError(
'ERROR misorder {} at level {} from {} on line {}'.format(
char, level, header_chars, i))
outfile.write(line.replace(char, HEADER_CHAR_LEVELS[level]))
else:
outfile.write(line)
print '{} -> {}'.format(outfile.name, filename)
shutil.move(outfile.name, filename)
return header_chars
def main():
filenames = sys.argv[1:]
for filename in filenames:
replace_header_chars(filename)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment