Skip to content

Update script to correctly handle new prelude style #494

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 110 additions & 42 deletions contrib/rst_update_prelude.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
"""
Currently, every module needs to contain a 'prelude' that
is expected to have the same content across every module.
This script is designed to "fix" the prelude when
a required content is updated / added.

To better organize this content, the default prelude
file uses RST containers to indicate where each specific
content begins. These sections are as follows:
BEGIN - any beginning matter
ROLES - common RST roles
SYMBOLS - common symbol replacements
REQUIRES - module-specific content
PROVIDES - module-specific content
END - end of prelude (contains the rest of the module).
In addition, anything appearing before BEGIN will be
saved as well.

The general process is to use 'split' to break
the module into sections and use the prelude section
name as the key. Anything appearing before BEGIN
will use FIRST_KEY as the key. We then compare the
actual to expected content only for BEGIN, SYMBOLS,
and ROLES). If there is a difference, the actual
content is updated. (The remaining sections are considered
module-specific).
After comparison, the sections are written out in the
same order they were read in (either to stdout or
back to the original file).
"""

import os
import sys
import argparse
Expand All @@ -6,15 +37,84 @@

CWD = Path(sys.argv[0]).resolve().parents[1]

"""
Flag used to split file into pieces
"""
PRELUDE_FLAG = "container:: PRELUDE "

FIRST_KEY = "000"

"""
Dictionary used to store expected prelude pieces
"""
EXPECTED = {}


"""
Populate the expected values from the predefined prelude
"""


def load_prelude(filename):
global EXPECTED

with open(filename, "rt") as file:
content = file.read()
pieces = content.split(PRELUDE_FLAG)
EXPECTED[FIRST_KEY] = pieces[0]
for section in pieces[1:]:
name, content = section.split("\n", 1)
EXPECTED[name] = content

def section_start(l):
# Section/Chapter/Slide separator
if len(l) > 2 and l[0] == l[1] and l[1] == l[2] and l[0] in "*-=+":
return True
# include another file
elif "include::" in l:
return True
return False

"""
Compare 'filename' contents to the expected contents.
If no changes are necessary, the file is not modified
"""


def process_file(filename, in_place):

ACTUAL = {}
pieces = None
update_required = False

with open(filename, "rt") as file:
content = file.read()
pieces = content.split(PRELUDE_FLAG)
ACTUAL[FIRST_KEY] = pieces[0]
for section in pieces[1:]:
name, content = section.split("\n", 1)
ACTUAL[name] = content

for key in ACTUAL.keys():
if not key in EXPECTED.keys():
if in_place:
print(" removing " + key)
del ACTUAL[key]
update_required = True

elif key == "BEGIN" or key == "ROLES" or key == "SYMBOLS":
if ACTUAL[key] != EXPECTED[key]:
if in_place:
print(" updating " + key)
ACTUAL[key] = EXPECTED[key]
update_required = True

for key in EXPECTED.keys():
if not key in ACTUAL.keys():
if in_place:
print(" adding " + key)
ACTUAL[key] = EXPECTED[key]
update_required = True

if update_required:
f_out = open(filename, "wt") if in_place else sys.stdout
for key in ACTUAL.keys():
if key == FIRST_KEY:
f_out.write(ACTUAL[key])
else:
f_out.write(PRELUDE_FLAG + key + "\n" + ACTUAL[key])


if __name__ == "__main__":
Expand All @@ -24,39 +124,7 @@ def section_start(l):
ap.add_argument("files", nargs="+")
args = ap.parse_args()

with open(args.prelude, "rt") as pf:
prelude_content = pf.read()

if prelude_content.endswith(os.linesep):
prelude_content = prelude_content[:-1]
load_prelude(args.prelude)

for f in args.files:
with open(f, "rt") as ff:
file_lines = ff.read().splitlines()

f_out = open(f, "wt") if args.in_place else sys.stdout

def print_out(*a, **kw):
kw.setdefault("file", f_out)
print(*a, **kw)

STATE_INIT, STATE_CHAPTER, STATE_END = 0, 1, 2
state = STATE_INIT
skip = 0
for l in file_lines:
if skip:
skip -= 1
print_out(l)
elif state == STATE_INIT:
if section_start(l):
state = STATE_CHAPTER
skip = 3
print_out(l)
elif state == STATE_CHAPTER:
if section_start(l):
print_out(prelude_content)
print_out()
print_out(l)
state = STATE_END
elif state == STATE_END:
print_out(l)
process_file(f, args.in_place)
Loading