From b707d3562c631b2ead03f79b2510ec6c9299db1b Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sun, 13 Jul 2014 20:10:35 +1700 Subject: [PATCH] [PATCH v3 3/5] doc/rst-man2any.py: Adjust to handle any output format, not just man pages --- a1/f44de8442f7ba881bae89b718ff81f9f085b5c | 298 ++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 a1/f44de8442f7ba881bae89b718ff81f9f085b5c diff --git a/a1/f44de8442f7ba881bae89b718ff81f9f085b5c b/a1/f44de8442f7ba881bae89b718ff81f9f085b5c new file mode 100644 index 000000000..74450f17a --- /dev/null +++ b/a1/f44de8442f7ba881bae89b718ff81f9f085b5c @@ -0,0 +1,298 @@ +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 + -- 2.26.2