Skip to content

Commit b98ef18

Browse files
committed
doc: Build keywords multitable automatically
Keywords are now listed in a plain text file. They're sorted in column-major order and rendered as a texinfo multitable in rust.texi. Fixes issue #1216.
1 parent 03f6060 commit b98ef18

File tree

4 files changed

+130
-68
lines changed

4 files changed

+130
-68
lines changed

doc/keywords.txt

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## Add Rust keywords here. Lines start with '#' are ignored
2+
3+
alt any as assert
4+
be bind block bool break
5+
char check claim const cont
6+
do
7+
else export
8+
f32 f64 fail false float fn for
9+
i16 i32 i64 i8 if import in int
10+
lambda let log
11+
mod mutable
12+
native note
13+
obj
14+
prove pure
15+
resource ret
16+
self str syntax
17+
tag true type
18+
u16 u32 u64 u8 uint unchecked unsafe use
19+
vec
20+
when while with

doc/rust.texi

+1-66
Original file line numberDiff line numberDiff line change
@@ -615,72 +615,7 @@ The keywords are:
615615

616616
@sp 2
617617

618-
@multitable @columnfractions .15 .15 .15 .15 .15
619-
@item @code{alt}
620-
@tab @code{const}
621-
@tab @code{i32}
622-
@tab @code{note}
623-
@tab @code{u32}
624-
@item @code{any}
625-
@tab @code{cont}
626-
@tab @code{i64}
627-
@tab @code{obj}
628-
@tab @code{u64}
629-
@item @code{as}
630-
@tab @code{do}
631-
@tab @code{i8}
632-
@tab @code{prove}
633-
@tab @code{u8}
634-
@item @code{assert}
635-
@tab @code{else}
636-
@tab @code{if}
637-
@tab @code{pure}
638-
@tab @code{uint}
639-
@item @code{}
640-
@tab @code{export}
641-
@tab @code{import}
642-
@tab @code{resource}
643-
@tab @code{unchecked}
644-
@item @code{be}
645-
@tab @code{f32}
646-
@tab @code{in}
647-
@tab @code{ret}
648-
@tab @code{unsafe}
649-
@item @code{bind}
650-
@tab @code{f64}
651-
@tab @code{int}
652-
@tab @code{self}
653-
@tab @code{use}
654-
@item @code{block}
655-
@tab @code{fail}
656-
@tab @code{lambda}
657-
@tab @code{str}
658-
@tab @code{vec}
659-
@item @code{bool}
660-
@tab @code{false}
661-
@tab @code{let}
662-
@tab @code{syntax}
663-
@tab @code{when}
664-
@item @code{break}
665-
@tab @code{float}
666-
@tab @code{log}
667-
@tab @code{tag}
668-
@tab @code{while}
669-
@item @code{char}
670-
@tab @code{fn}
671-
@tab @code{mod}
672-
@tab @code{true}
673-
@tab @code{with}
674-
@item @code{check}
675-
@tab @code{for}
676-
@tab @code{mutable}
677-
@tab @code{type}
678-
@tab @code{}
679-
@item @code{claim}
680-
@tab @code{i16}
681-
@tab @code{native}
682-
@tab @code{u16}
683-
@end multitable
618+
@include keywords.texi
684619

685620
@node Ref.Lex.Res
686621
@subsection Ref.Lex.Res

mk/docs.mk

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@
44

55
docs: $(DOCS)
66

7+
doc/keywords.texi: $(S)doc/keywords.txt $(S)src/etc/gen-keywords-table.py
8+
@$(call E, gen-keywords-table: $@)
9+
$(Q)$(S)src/etc/gen-keywords-table.py
10+
711
doc/version.texi: $(MKFILES) rust.texi
812
@$(call E, version-stamp: $@)
913
$(Q)echo "@macro gitversion" >$@
1014
$(Q)echo "$(CFG_VERSION)" >>$@
1115
$(Q)echo "@end macro" >>$@
1216

13-
doc/%.pdf: %.texi doc/version.texi
17+
doc/%.pdf: %.texi doc/version.texi doc/keywords.texi
1418
@$(call E, texi2pdf: $@)
1519
@# LC_COLLATE=C works around a bug in texi2dvi; see
1620
@# https://bugzilla.redhat.com/show_bug.cgi?id=583011 and
1721
@# https://github.com/graydon/rust/issues/1134
1822
$(Q)LC_COLLATE=C texi2pdf --silent --batch -I doc -o $@ --clean $<
1923

20-
doc/%.html: %.texi doc/version.texi
24+
doc/%.html: %.texi doc/version.texi doc/keywords.texi
2125
@$(call E, makeinfo: $@)
2226
$(Q)makeinfo -I doc --html --ifhtml --force --no-split --output=$@ $<
2327

src/etc/gen-keywords-table.py

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/usr/bin/env python
2+
3+
import sys
4+
import os.path
5+
6+
def scrub(b):
7+
if sys.version_info >= (3,) and type(b) == bytes:
8+
return b.decode('ascii')
9+
else:
10+
return b
11+
12+
src_dir = scrub(os.getenv("CFG_SRC_DIR"))
13+
if not src_dir:
14+
raise Exception("missing env var CFG_SRC_DIR")
15+
16+
17+
def get_keywords():
18+
keywords_file = os.path.join(src_dir, "doc", "keywords.txt")
19+
keywords = []
20+
for line in open(keywords_file).readlines():
21+
if not line or line.startswith('#'):
22+
continue
23+
for kw in line.split():
24+
if kw.isalnum():
25+
keywords.append(kw)
26+
return keywords
27+
28+
29+
def sort(keywords, ncols):
30+
"""Sort keywords in a column-major ordered table.
31+
32+
Args:
33+
keywords: List of keywords
34+
ncols: Number of columns to be sorted
35+
"""
36+
## sort and remove duplicates
37+
keywords = sorted(list(set(keywords)))
38+
sz = len(keywords)
39+
40+
if sz % ncols > 0:
41+
nrows = sz / ncols + 1
42+
else:
43+
nrows = sz / ncols
44+
45+
result = []
46+
max = ncols * nrows
47+
for i in xrange(0, max):
48+
result.append("")
49+
50+
for i in xrange(1, sz+1):
51+
if i % nrows == 0:
52+
extra = 0
53+
else:
54+
extra = 1
55+
pos = (((i + (nrows - 1)) % nrows) * ncols) + \
56+
(i / nrows + extra)
57+
result[pos - 1] = keywords[i - 1]
58+
59+
return rows(result, ncols)
60+
61+
62+
def rows(keywords, ncols):
63+
"""Split input list of keywords into rows.
64+
65+
Each contains ncols or ncols-1 elements.
66+
67+
Args:
68+
keywords: List of keywords sorted in column-major order
69+
ncols: Number of columns
70+
"""
71+
sz = len(keywords)
72+
result = []
73+
i = 0
74+
while i < sz:
75+
if i + ncols < sz:
76+
se = i + ncols
77+
else:
78+
se = sz
79+
result.append(keywords[i:se])
80+
i = se
81+
return result
82+
83+
84+
def table(rows):
85+
"""Render rows in a texinfo multitable."""
86+
result = ["@multitable @columnfractions .15 .15 .15 .15 .15\n"]
87+
for row in rows:
88+
result += ["@item @code{" + row[0] + "}\n"];
89+
for e in row[1:]:
90+
result += ["@tab @code{" + e + "}\n"];
91+
result += ["@end multitable\n"];
92+
return result
93+
94+
95+
def main(oargs):
96+
keywords = get_keywords()
97+
out_file = open(os.path.join("doc", "keywords.texi"), 'w')
98+
for line in table(sort(keywords, 5)):
99+
out_file.write(line)
100+
out_file.close()
101+
102+
if __name__ == '__main__':
103+
main(sys.argv[1:])

0 commit comments

Comments
 (0)