From 2ac63801d2d5b7b681041cac28f6f7571b39f95e Mon Sep 17 00:00:00 2001 From: Haitao Li Date: Wed, 23 Nov 2011 23:24:56 +0800 Subject: [PATCH] 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. --- doc/keywords.txt | 20 +++++++ doc/rust.texi | 67 +--------------------- mk/docs.mk | 8 ++- src/etc/gen-keywords-table.py | 103 ++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 68 deletions(-) create mode 100644 doc/keywords.txt create mode 100755 src/etc/gen-keywords-table.py diff --git a/doc/keywords.txt b/doc/keywords.txt new file mode 100644 index 00000000000..c01bc2c8ee4 --- /dev/null +++ b/doc/keywords.txt @@ -0,0 +1,20 @@ +## Add Rust keywords here. Lines start with '#' are ignored + +alt any as assert +be bind block bool break +char check claim const cont +do +else export +f32 f64 fail false float fn for +i16 i32 i64 i8 if import in int +lambda let log +mod mutable +native note +obj +prove pure +resource ret +self str syntax +tag true type +u16 u32 u64 u8 uint unchecked unsafe use +vec +when while with diff --git a/doc/rust.texi b/doc/rust.texi index 050b76eb15f..86cdee2b4db 100644 --- a/doc/rust.texi +++ b/doc/rust.texi @@ -615,72 +615,7 @@ The keywords are: @sp 2 -@multitable @columnfractions .15 .15 .15 .15 .15 -@item @code{alt} -@tab @code{const} -@tab @code{i32} -@tab @code{note} -@tab @code{u32} -@item @code{any} -@tab @code{cont} -@tab @code{i64} -@tab @code{obj} -@tab @code{u64} -@item @code{as} -@tab @code{do} -@tab @code{i8} -@tab @code{prove} -@tab @code{u8} -@item @code{assert} -@tab @code{else} -@tab @code{if} -@tab @code{pure} -@tab @code{uint} -@item @code{} -@tab @code{export} -@tab @code{import} -@tab @code{resource} -@tab @code{unchecked} -@item @code{be} -@tab @code{f32} -@tab @code{in} -@tab @code{ret} -@tab @code{unsafe} -@item @code{bind} -@tab @code{f64} -@tab @code{int} -@tab @code{self} -@tab @code{use} -@item @code{block} -@tab @code{fail} -@tab @code{lambda} -@tab @code{str} -@tab @code{vec} -@item @code{bool} -@tab @code{false} -@tab @code{let} -@tab @code{syntax} -@tab @code{when} -@item @code{break} -@tab @code{float} -@tab @code{log} -@tab @code{tag} -@tab @code{while} -@item @code{char} -@tab @code{fn} -@tab @code{mod} -@tab @code{true} -@tab @code{with} -@item @code{check} -@tab @code{for} -@tab @code{mutable} -@tab @code{type} -@tab @code{} -@item @code{claim} -@tab @code{i16} -@tab @code{native} -@tab @code{u16} -@end multitable +@include keywords.texi @node Ref.Lex.Res @subsection Ref.Lex.Res diff --git a/mk/docs.mk b/mk/docs.mk index f65ea694050..62f67bbf105 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -4,20 +4,24 @@ docs: $(DOCS) +doc/keywords.texi: $(S)doc/keywords.txt $(S)src/etc/gen-keywords-table.py + @$(call E, gen-keywords-table: $@) + $(Q)$(S)src/etc/gen-keywords-table.py + doc/version.texi: $(MKFILES) rust.texi @$(call E, version-stamp: $@) $(Q)echo "@macro gitversion" >$@ $(Q)echo "$(CFG_VERSION)" >>$@ $(Q)echo "@end macro" >>$@ -doc/%.pdf: %.texi doc/version.texi +doc/%.pdf: %.texi doc/version.texi doc/keywords.texi @$(call E, texi2pdf: $@) @# LC_COLLATE=C works around a bug in texi2dvi; see @# https://bugzilla.redhat.com/show_bug.cgi?id=583011 and @# https://github.com/graydon/rust/issues/1134 $(Q)LC_COLLATE=C texi2pdf --silent --batch -I doc -o $@ --clean $< -doc/%.html: %.texi doc/version.texi +doc/%.html: %.texi doc/version.texi doc/keywords.texi @$(call E, makeinfo: $@) $(Q)makeinfo -I doc --html --ifhtml --force --no-split --output=$@ $< diff --git a/src/etc/gen-keywords-table.py b/src/etc/gen-keywords-table.py new file mode 100755 index 00000000000..ea7417e83f8 --- /dev/null +++ b/src/etc/gen-keywords-table.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python + +import sys +import os.path + +def scrub(b): + if sys.version_info >= (3,) and type(b) == bytes: + return b.decode('ascii') + else: + return b + +src_dir = scrub(os.getenv("CFG_SRC_DIR")) +if not src_dir: + raise Exception("missing env var CFG_SRC_DIR") + + +def get_keywords(): + keywords_file = os.path.join(src_dir, "doc", "keywords.txt") + keywords = [] + for line in open(keywords_file).readlines(): + if not line or line.startswith('#'): + continue + for kw in line.split(): + if kw.isalnum(): + keywords.append(kw) + return keywords + + +def sort(keywords, ncols): + """Sort keywords in a column-major ordered table. + + Args: + keywords: List of keywords + ncols: Number of columns to be sorted + """ + ## sort and remove duplicates + keywords = sorted(list(set(keywords))) + sz = len(keywords) + + if sz % ncols > 0: + nrows = sz / ncols + 1 + else: + nrows = sz / ncols + + result = [] + max = ncols * nrows + for i in xrange(0, max): + result.append("") + + for i in xrange(1, sz+1): + if i % nrows == 0: + extra = 0 + else: + extra = 1 + pos = (((i + (nrows - 1)) % nrows) * ncols) + \ + (i / nrows + extra) + result[pos - 1] = keywords[i - 1] + + return rows(result, ncols) + + +def rows(keywords, ncols): + """Split input list of keywords into rows. + + Each contains ncols or ncols-1 elements. + + Args: + keywords: List of keywords sorted in column-major order + ncols: Number of columns + """ + sz = len(keywords) + result = [] + i = 0 + while i < sz: + if i + ncols < sz: + se = i + ncols + else: + se = sz + result.append(keywords[i:se]) + i = se + return result + + +def table(rows): + """Render rows in a texinfo multitable.""" + result = ["@multitable @columnfractions .15 .15 .15 .15 .15\n"] + for row in rows: + result += ["@item @code{" + row[0] + "}\n"]; + for e in row[1:]: + result += ["@tab @code{" + e + "}\n"]; + result += ["@end multitable\n"]; + return result + + +def main(oargs): + keywords = get_keywords() + out_file = open(os.path.join("doc", "keywords.texi"), 'w') + for line in table(sort(keywords, 5)): + out_file.write(line) + out_file.close() + +if __name__ == '__main__': + main(sys.argv[1:])