Skip to content

Commit 338e152

Browse files
Merge branch 'slides/212-rst_update_prelude-py-needs-to-work' into 'master'
Resolve "rst_update_prelude.py needs to work" Closes #212 See merge request feng/training/material!283
2 parents 3d2eb8d + c1d62c7 commit 338e152

File tree

1 file changed

+110
-42
lines changed

1 file changed

+110
-42
lines changed

contrib/rst_update_prelude.py

Lines changed: 110 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
1+
"""
2+
Currently, every module needs to contain a 'prelude' that
3+
is expected to have the same content across every module.
4+
This script is designed to "fix" the prelude when
5+
a required content is updated / added.
6+
7+
To better organize this content, the default prelude
8+
file uses RST containers to indicate where each specific
9+
content begins. These sections are as follows:
10+
BEGIN - any beginning matter
11+
ROLES - common RST roles
12+
SYMBOLS - common symbol replacements
13+
REQUIRES - module-specific content
14+
PROVIDES - module-specific content
15+
END - end of prelude (contains the rest of the module).
16+
In addition, anything appearing before BEGIN will be
17+
saved as well.
18+
19+
The general process is to use 'split' to break
20+
the module into sections and use the prelude section
21+
name as the key. Anything appearing before BEGIN
22+
will use FIRST_KEY as the key. We then compare the
23+
actual to expected content only for BEGIN, SYMBOLS,
24+
and ROLES). If there is a difference, the actual
25+
content is updated. (The remaining sections are considered
26+
module-specific).
27+
After comparison, the sections are written out in the
28+
same order they were read in (either to stdout or
29+
back to the original file).
30+
"""
31+
132
import os
233
import sys
334
import argparse
@@ -6,15 +37,84 @@
637

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

40+
"""
41+
Flag used to split file into pieces
42+
"""
43+
PRELUDE_FLAG = "container:: PRELUDE "
44+
45+
FIRST_KEY = "000"
46+
47+
"""
48+
Dictionary used to store expected prelude pieces
49+
"""
50+
EXPECTED = {}
51+
52+
53+
"""
54+
Populate the expected values from the predefined prelude
55+
"""
56+
57+
58+
def load_prelude(filename):
59+
global EXPECTED
60+
61+
with open(filename, "rt") as file:
62+
content = file.read()
63+
pieces = content.split(PRELUDE_FLAG)
64+
EXPECTED[FIRST_KEY] = pieces[0]
65+
for section in pieces[1:]:
66+
name, content = section.split("\n", 1)
67+
EXPECTED[name] = content
968

10-
def section_start(l):
11-
# Section/Chapter/Slide separator
12-
if len(l) > 2 and l[0] == l[1] and l[1] == l[2] and l[0] in "*-=+":
13-
return True
14-
# include another file
15-
elif "include::" in l:
16-
return True
17-
return False
69+
70+
"""
71+
Compare 'filename' contents to the expected contents.
72+
If no changes are necessary, the file is not modified
73+
"""
74+
75+
76+
def process_file(filename, in_place):
77+
78+
ACTUAL = {}
79+
pieces = None
80+
update_required = False
81+
82+
with open(filename, "rt") as file:
83+
content = file.read()
84+
pieces = content.split(PRELUDE_FLAG)
85+
ACTUAL[FIRST_KEY] = pieces[0]
86+
for section in pieces[1:]:
87+
name, content = section.split("\n", 1)
88+
ACTUAL[name] = content
89+
90+
for key in ACTUAL.keys():
91+
if not key in EXPECTED.keys():
92+
if in_place:
93+
print(" removing " + key)
94+
del ACTUAL[key]
95+
update_required = True
96+
97+
elif key == "BEGIN" or key == "ROLES" or key == "SYMBOLS":
98+
if ACTUAL[key] != EXPECTED[key]:
99+
if in_place:
100+
print(" updating " + key)
101+
ACTUAL[key] = EXPECTED[key]
102+
update_required = True
103+
104+
for key in EXPECTED.keys():
105+
if not key in ACTUAL.keys():
106+
if in_place:
107+
print(" adding " + key)
108+
ACTUAL[key] = EXPECTED[key]
109+
update_required = True
110+
111+
if update_required:
112+
f_out = open(filename, "wt") if in_place else sys.stdout
113+
for key in ACTUAL.keys():
114+
if key == FIRST_KEY:
115+
f_out.write(ACTUAL[key])
116+
else:
117+
f_out.write(PRELUDE_FLAG + key + "\n" + ACTUAL[key])
18118

19119

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

27-
with open(args.prelude, "rt") as pf:
28-
prelude_content = pf.read()
29-
30-
if prelude_content.endswith(os.linesep):
31-
prelude_content = prelude_content[:-1]
127+
load_prelude(args.prelude)
32128

33129
for f in args.files:
34-
with open(f, "rt") as ff:
35-
file_lines = ff.read().splitlines()
36-
37-
f_out = open(f, "wt") if args.in_place else sys.stdout
38-
39-
def print_out(*a, **kw):
40-
kw.setdefault("file", f_out)
41-
print(*a, **kw)
42-
43-
STATE_INIT, STATE_CHAPTER, STATE_END = 0, 1, 2
44-
state = STATE_INIT
45-
skip = 0
46-
for l in file_lines:
47-
if skip:
48-
skip -= 1
49-
print_out(l)
50-
elif state == STATE_INIT:
51-
if section_start(l):
52-
state = STATE_CHAPTER
53-
skip = 3
54-
print_out(l)
55-
elif state == STATE_CHAPTER:
56-
if section_start(l):
57-
print_out(prelude_content)
58-
print_out()
59-
print_out(l)
60-
state = STATE_END
61-
elif state == STATE_END:
62-
print_out(l)
130+
process_file(f, args.in_place)

0 commit comments

Comments
 (0)