Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 78B29431FC0 for ; Sat, 12 Jul 2014 20:12:19 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SpCliUMAQKww for ; Sat, 12 Jul 2014 20:12:12 -0700 (PDT) Received: from qmta12.emeryville.ca.mail.comcast.net (qmta12.emeryville.ca.mail.comcast.net [76.96.27.227]) by olra.theworths.org (Postfix) with ESMTP id 6D29B431FBD for ; Sat, 12 Jul 2014 20:11:48 -0700 (PDT) Received: from omta01.emeryville.ca.mail.comcast.net ([76.96.30.11]) by qmta12.emeryville.ca.mail.comcast.net with comcast id RfAY1o0030EPcho01fBndl; Sun, 13 Jul 2014 03:11:48 +0000 Received: from odin.tremily.us ([24.18.63.50]) by omta01.emeryville.ca.mail.comcast.net with comcast id RfBU1o00n152l3L8MfBlCe; Sun, 13 Jul 2014 03:11:47 +0000 Received: from mjolnir.tremily.us (unknown [192.168.0.150]) by odin.tremily.us (Postfix) with ESMTPS id 48C551286F05; Sat, 12 Jul 2014 20:11:27 -0700 (PDT) Received: (nullmailer pid 31452 invoked by uid 1000); Sun, 13 Jul 2014 03:10:44 -0000 From: "W. Trevor King" To: notmuch@notmuchmail.org Subject: [PATCH v3 3/5] doc/rst-man2any.py: Adjust to handle any output format, not just man pages Date: Sat, 12 Jul 2014 20:10:35 -0700 Message-Id: X-Mailer: git-send-email 1.9.1.353.gc66d89d In-Reply-To: References: In-Reply-To: References: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=comcast.net; s=q20140121; t=1405221108; bh=3WWFZti79msppoZ960v8bCxxX9vSsferWsk0hyU7J+A=; h=Received:Received:Received:Received:From:To:Subject:Date: Message-Id; b=DaOUAM/puyCay51B44Rg51PGxWdR1gh75+H1swojVHSlsAaVWrN+PbiE7L2JPS/yz 85HpQfMpTiGM6sTqteZ/rLUq711z5pGYepkQy/KidT86cyF3POdl8ZVAcbTfn/i4Ph vX8wEmOvCsHphx8dA/pTdHHYBGgWprdin5eSSj0WP/SAWR8KA1aj4w+GoMVq+RSlO4 ECmCoNsYjlEJ+p7qLEMIeHSQzqCSnXH1vGJlCt+KWsT7b5XBDUnh7ReubYXG4r/2o5 OFOXBZ8oXW/3tSYUjYN+UJR4sO/2UJjZOqF+W/C/e4hk4WHKQkrsCggqOPMTUhuQ0Q 0vzQmyNJEiydw== Cc: Tomi Ollila X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Jul 2014 03:12:19 -0000 For example, with these changes we can build HTML output using: $ rst-man2any.py -c rst2html -i ${SRCDIR} -o ${OUTDIR} -e html The extension adjustment ensures that the output filenames from the above command match what we currently generate with sphinx-html. Adding argparse handling at the top of the script tipped this over into "complicated enough to refactor" for me, so I've shifted the single-file-conversion logic into a new convert() function and streamlined things a bit. --- doc/Makefile.local | 4 +- doc/prerst2man.py | 66 --------------------------------- doc/rst-man2any.py | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 68 deletions(-) delete mode 100644 doc/prerst2man.py create mode 100755 doc/rst-man2any.py diff --git a/doc/Makefile.local b/doc/Makefile.local index d96cdd5..045f823 100644 --- a/doc/Makefile.local +++ b/doc/Makefile.local @@ -7,7 +7,7 @@ SPHINXOPTS := -q SPHINXBUILD = sphinx-build DOCBUILDDIR := $(dir)/_build -prerst2man := python $(srcdir)/$(dir)/prerst2man.py +rstman2any := python $(srcdir)/$(dir)/rst-man2any.py mkdocdeps := python $(srcdir)/$(dir)/mkdocdeps.py # Internal variables. @@ -49,7 +49,7 @@ ifeq ($(HAVE_SPHINX),1) mv $(DOCBUILDDIR)/man/*.$${section} $(DOCBUILDDIR)/man/man$${section}; \ done else ifeq ($(HAVE_RST2MAN),1) - $(prerst2man) "$(RST2MAN)" $(srcdir)/doc $(DOCBUILDDIR)/man + $(rstman2any) --converter "$(RST2MAN)" --input $(srcdir)/doc --output $(DOCBUILDDIR)/man else @echo "Fatal: build dependency fail." @false diff --git a/doc/prerst2man.py b/doc/prerst2man.py deleted file mode 100644 index 7d78e9b..0000000 --- a/doc/prerst2man.py +++ /dev/null @@ -1,66 +0,0 @@ -import sys -from datetime import date -from os.path import dirname, isdir -from os import makedirs, system -import re - -rst2man = sys.argv[1] -sourcedir = sys.argv[2] -outdir = sys.argv[3] - -sys.path.insert(0, sourcedir) -import conf - - -if not isdir(outdir): - makedirs(outdir, 0o755) - - -def header(file, startdocname, command, description, authors, section): - file.write(""" -{0:s} -{1:s} -{2:s} - -:Date: {3:s} -:Version: {4:s} -:Manual section: {5:d} -:Manual group: {6:s} - -""".format( -'-' * len(description), -description, -'-' * len(description), -date.today().isoformat(), conf.release, section, conf.project)) - -blankre = re.compile("^\s*$") -for page in conf.man_pages: - outdirname = outdir + '/' + dirname(page[0]) - if not isdir(outdirname): - makedirs(outdirname, 0o755) - filename = outdir + '/' + page[0] + '.rst' - outfile = open(filename, 'w') - infile = open(sourcedir + '/' + page[0] + '.rst', 'r') - - # this is a crude hack. We look for the first blank line, and - # insert the rst2man header there. - # - # XXX consider really parsing input - - count = 0 - lines = infile.readlines() - for line in lines: - outfile.write(line) - if (blankre.match(line)): - break - count = count + 1 - - del lines[0:count + 1] - - header(outfile, *page) - - outfile.write("".join(lines)) - outfile.close() - - system('set -x; {0} {1} {2}/{3}.{4}' - .format(rst2man, filename, outdir, page[0], page[4])) diff --git a/doc/rst-man2any.py b/doc/rst-man2any.py new file mode 100755 index 0000000..52a4f9e --- /dev/null +++ b/doc/rst-man2any.py @@ -0,0 +1,105 @@ +#!/usr/bin/python + +import argparse +import datetime +import os +import sys + + +def header(stream, description, authors, section, group, version): + "Write a man-page's ReST headers to 'stream'." + if len(authors) != 1: + raise NotImplementedError( + 'cannot handle {count} authors ({authors}'.format( + count=len(authors), authors=authors)) + stream.write('\n'.join([ + '{description_rule}', + '{description}', + '{description_rule}', + '', + ':Author: {author}', + ':Date: {date}', + ':Version: {version}', + ':Manual section: {section:d}', + ':Manual group: {group}', + '', + '']).format( + description=description, + description_rule='-' * len(description), + author=authors[0], + date=datetime.date.today().isoformat(), + version=version, + section=section, + group=group)) + + +def convert(startdocname, description, authors, section, + group, version, source_dir, output_dir, command, extension=None): + """Convert the ReST source at path to the target format in 'output_dir'. + + The initial arguments (startdocname through section) follow + Sphinx's man_pages option [1]. + + [1]: http://sphinx-doc.org/config.html#confval-man_pages + """ + source_path = os.path.join(source_dir, startdocname) + '.rst' + output_base = os.path.join(output_dir, startdocname) + temp_path = output_base + '.rst' + if extension: + ext = extension + else: + ext = str(section) + output_path = '{base}.{ext}'.format(base=output_base, ext=ext) + dirname = os.path.dirname(output_path) + if not os.path.isdir(dirname): + os.makedirs(dirname, 0o755) + with open(source_path, 'r') as source: + with open(temp_path, 'w') as temp: + # this is a crude hack. We look for the first blank line, and + # insert the man-page headers there. + # + # XXX consider really parsing input + need_header = True + for line in source: + temp.write(line) + if need_header and not line.strip(): + header( + stream=temp, description=description, authors=authors, + section=section, group=group, version=version) + need_header = False + os.system('set -x; {command} {source_path} {output_path}'.format( + command=command, + source_path=temp_path, + output_path=output_path)) + + +if __name__ == '__main__': + import argparse + + parser = argparse.ArgumentParser( + description='Convert reStructuredText man pages to other formats.') + parser.add_argument( + '-i', '--input', default='_build', + help='Input directory') + parser.add_argument( + '-o', '--output', default='.', + help='Output directory') + parser.add_argument( + '-c', '--converter', default='rst2man', + help='ReST converter for your target output') + parser.add_argument( + '-e', '--extension', + help='Optional extension for the output files') + + args = parser.parse_args() + + sys.path.insert(0, args.input) + import conf + + for startdocname, name, description, authors, section in conf.man_pages: + convert( + startdocname=startdocname, description=description, + authors=authors, section=section, group=conf.project, + version=conf.release, source_dir=args.input, + output_dir=args.output, command=args.converter, + extension=args.extension) -- 1.9.1.353.gc66d89d