Convert PEP index to ReST (#705)
Keeps Python 3.5 compatibility, as that's what pythondotorg currently still uses.
This commit is contained in:
parent
0630155b47
commit
d18a264e4b
|
@ -1,4 +1,5 @@
|
||||||
pep-0000.txt
|
pep-0000.txt
|
||||||
|
pep-0000.rst
|
||||||
pep-????.html
|
pep-????.html
|
||||||
__pycache__
|
__pycache__
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
7
Makefile
7
Makefile
|
@ -15,13 +15,13 @@ PYTHON=python3
|
||||||
.rst.html:
|
.rst.html:
|
||||||
@$(PYTHON) $(PEP2HTML) $<
|
@$(PYTHON) $(PEP2HTML) $<
|
||||||
|
|
||||||
TARGETS= $(patsubst %.rst,%.html,$(wildcard pep-????.rst)) $(patsubst %.txt,%.html,$(wildcard pep-????.txt)) pep-0000.html
|
TARGETS= $(patsubst %.rst,%.html,$(wildcard pep-????.rst)) $(patsubst %.txt,%.html,$(wildcard pep-????.txt)) pep-0000.html
|
||||||
|
|
||||||
all: pep-0000.txt $(TARGETS)
|
all: pep-0000.rst $(TARGETS)
|
||||||
|
|
||||||
$(TARGETS): pep2html.py
|
$(TARGETS): pep2html.py
|
||||||
|
|
||||||
pep-0000.txt: $(wildcard pep-????.txt) $(wildcard pep-????.rst) $(wildcard pep0/*.py)
|
pep-0000.rst: $(wildcard pep-????.txt) $(wildcard pep-????.rst) $(wildcard pep0/*.py) genpepindex.py
|
||||||
$(PYTHON) genpepindex.py .
|
$(PYTHON) genpepindex.py .
|
||||||
|
|
||||||
rss:
|
rss:
|
||||||
|
@ -31,6 +31,7 @@ install:
|
||||||
echo "Installing is not necessary anymore. It will be done in post-commit."
|
echo "Installing is not necessary anymore. It will be done in post-commit."
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
-rm pep-0000.rst
|
||||||
-rm pep-0000.txt
|
-rm pep-0000.txt
|
||||||
-rm *.html
|
-rm *.html
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ def main(argv):
|
||||||
peps = []
|
peps = []
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
for file_path in os.listdir(path):
|
for file_path in os.listdir(path):
|
||||||
if file_path == 'pep-0000.txt':
|
if file_path.startswith('pep-0000.'):
|
||||||
continue
|
continue
|
||||||
abs_file_path = os.path.join(path, file_path)
|
abs_file_path = os.path.join(path, file_path)
|
||||||
if not os.path.isfile(abs_file_path):
|
if not os.path.isfile(abs_file_path):
|
||||||
|
@ -61,7 +61,7 @@ def main(argv):
|
||||||
else:
|
else:
|
||||||
raise ValueError("argument must be a directory or file path")
|
raise ValueError("argument must be a directory or file path")
|
||||||
|
|
||||||
with codecs.open('pep-0000.txt', 'w', encoding='UTF-8') as pep0_file:
|
with codecs.open('pep-0000.rst', 'w', encoding='UTF-8') as pep0_file:
|
||||||
write_pep0(peps, pep0_file)
|
write_pep0(peps, pep0_file)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -1,44 +1,43 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import sys
|
text_type = str
|
||||||
|
|
||||||
if sys.version_info[0] > 2:
|
|
||||||
text_type = str
|
|
||||||
else:
|
|
||||||
text_type = unicode
|
|
||||||
|
|
||||||
title_length = 55
|
title_length = 55
|
||||||
column_format = (u' %(type)1s%(status)1s %(number)4s %(title)-' +
|
author_length = 40
|
||||||
text_type(title_length) + u's %(authors)-s')
|
table_separator = "== ==== " + "="*title_length + " " + "="*author_length
|
||||||
|
column_format = (
|
||||||
|
'%(type)1s%(status)1s %(number)4s %(title)-{title_length}s %(authors)-s'
|
||||||
|
).format(title_length=title_length)
|
||||||
|
|
||||||
header = u"""PEP: 0
|
header = """\
|
||||||
|
PEP: 0
|
||||||
Title: Index of Python Enhancement Proposals (PEPs)
|
Title: Index of Python Enhancement Proposals (PEPs)
|
||||||
Version: N/A
|
Version: N/A
|
||||||
Last-Modified: %s
|
Last-Modified: %s
|
||||||
Author: David Goodger <goodger@python.org>,
|
Author: python-dev <python-dev@python.org>
|
||||||
Barry Warsaw <barry@python.org>
|
|
||||||
Status: Active
|
Status: Active
|
||||||
Type: Informational
|
Type: Informational
|
||||||
|
Content-Type: text/x-rst
|
||||||
Created: 13-Jul-2000
|
Created: 13-Jul-2000
|
||||||
"""
|
"""
|
||||||
|
|
||||||
intro = u"""
|
intro = """\
|
||||||
This PEP contains the index of all Python Enhancement Proposals,
|
This PEP contains the index of all Python Enhancement Proposals,
|
||||||
known as PEPs. PEP numbers are assigned by the PEP editors, and
|
known as PEPs. PEP numbers are assigned by the PEP editors, and
|
||||||
once assigned are never changed[1]. The version control history[2] of
|
once assigned are never changed [1_]. The version control history [2_] of
|
||||||
the PEP texts represent their historical record.
|
the PEP texts represent their historical record.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
references = u"""
|
references = """\
|
||||||
[1] PEP 1: PEP Purpose and Guidelines
|
.. [1] PEP 1: PEP Purpose and Guidelines
|
||||||
[2] View PEP history online
|
.. [2] View PEP history online: https://github.com/python/peps
|
||||||
https://github.com/python/peps
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
footer = u"""
|
footer = """\
|
||||||
Local Variables:
|
..
|
||||||
mode: indented-text
|
Local Variables:
|
||||||
indent-tabs-mode: nil
|
mode: indented-text
|
||||||
sentence-end-double-space: t
|
indent-tabs-mode: nil
|
||||||
fill-column: 70
|
sentence-end-double-space: t
|
||||||
coding: utf-8
|
fill-column: 70
|
||||||
End:"""
|
coding: utf-8
|
||||||
|
End:\
|
||||||
|
"""
|
||||||
|
|
208
pep0/output.py
208
pep0/output.py
|
@ -26,15 +26,13 @@ RESERVED = [
|
||||||
|
|
||||||
indent = u' '
|
indent = u' '
|
||||||
|
|
||||||
def write_column_headers(output):
|
def emit_column_headers(output):
|
||||||
"""Output the column headers for the PEP indices."""
|
"""Output the column headers for the PEP indices."""
|
||||||
column_headers = {'status': u'', 'type': u'', 'number': u'num',
|
column_headers = {'status': '.', 'type': '.', 'number': 'PEP',
|
||||||
'title': u'title', 'authors': u'owner'}
|
'title': 'PEP Title', 'authors': 'PEP Author(s)'}
|
||||||
|
print(constants.table_separator, file=output)
|
||||||
print(constants.column_format % column_headers, file=output)
|
print(constants.column_format % column_headers, file=output)
|
||||||
underline_headers = {}
|
print(constants.table_separator, file=output)
|
||||||
for key, value in column_headers.items():
|
|
||||||
underline_headers[key] = constants.text_type(len(value) * '-')
|
|
||||||
print(constants.column_format % underline_headers, file=output)
|
|
||||||
|
|
||||||
|
|
||||||
def sort_peps(peps):
|
def sort_peps(peps):
|
||||||
|
@ -93,7 +91,7 @@ def verify_email_addresses(peps):
|
||||||
authors_dict = {}
|
authors_dict = {}
|
||||||
for pep in peps:
|
for pep in peps:
|
||||||
for author in pep.authors:
|
for author in pep.authors:
|
||||||
# If this is the first time we have come across an author, add him.
|
# If this is the first time we have come across an author, add them.
|
||||||
if author not in authors_dict:
|
if author not in authors_dict:
|
||||||
authors_dict[author] = [author.email]
|
authors_dict[author] = [author.email]
|
||||||
else:
|
else:
|
||||||
|
@ -133,118 +131,160 @@ def sort_authors(authors_dict):
|
||||||
def normalized_last_first(name):
|
def normalized_last_first(name):
|
||||||
return len(unicodedata.normalize('NFC', name.last_first))
|
return len(unicodedata.normalize('NFC', name.last_first))
|
||||||
|
|
||||||
|
def emit_title(text, anchor, output, *, symbol="="):
|
||||||
|
print(".. _{anchor}:\n".format(anchor=anchor), file=output)
|
||||||
|
print(text, file=output)
|
||||||
|
print(symbol*len(text), file=output)
|
||||||
|
print(file=output)
|
||||||
|
|
||||||
|
def emit_subtitle(text, anchor, output):
|
||||||
|
emit_title(text, anchor, output, symbol="-")
|
||||||
|
|
||||||
|
def emit_pep_category(output, category, anchor, peps):
|
||||||
|
emit_subtitle(category, anchor, output)
|
||||||
|
emit_column_headers(output)
|
||||||
|
for pep in peps:
|
||||||
|
print(pep, file=output)
|
||||||
|
print(constants.table_separator, file=output)
|
||||||
|
print(file=output)
|
||||||
|
|
||||||
def write_pep0(peps, output=sys.stdout):
|
def write_pep0(peps, output=sys.stdout):
|
||||||
|
# PEP metadata
|
||||||
today = datetime.date.today().strftime("%Y-%m-%d")
|
today = datetime.date.today().strftime("%Y-%m-%d")
|
||||||
print(constants.header % today, file=output)
|
print(constants.header % today, file=output)
|
||||||
print(file=output)
|
print(file=output)
|
||||||
print(u"Introduction", file=output)
|
# Introduction
|
||||||
|
emit_title("Introduction", "intro", output)
|
||||||
print(constants.intro, file=output)
|
print(constants.intro, file=output)
|
||||||
print(file=output)
|
print(file=output)
|
||||||
print(u"Index by Category", file=output)
|
# PEPs by category
|
||||||
print(file=output)
|
|
||||||
write_column_headers(output)
|
|
||||||
(meta, info, provisional, accepted, open_,
|
(meta, info, provisional, accepted, open_,
|
||||||
finished, historical, deferred, dead) = sort_peps(peps)
|
finished, historical, deferred, dead) = sort_peps(peps)
|
||||||
|
emit_title("Index by Category", "by-category", output)
|
||||||
|
emit_pep_category(
|
||||||
|
category="Meta-PEPs (PEPs about PEPs or Processes)",
|
||||||
|
anchor="by-category-meta",
|
||||||
|
peps=meta,
|
||||||
|
output=output,
|
||||||
|
)
|
||||||
|
emit_pep_category(
|
||||||
|
category="Other Informational PEPs",
|
||||||
|
anchor="by-category-other-info",
|
||||||
|
peps=info,
|
||||||
|
output=output,
|
||||||
|
)
|
||||||
|
emit_pep_category(
|
||||||
|
category="Provisional PEPs (provisionally accepted; interface may still change)",
|
||||||
|
anchor="by-category-provisional",
|
||||||
|
peps=provisional,
|
||||||
|
output=output,
|
||||||
|
)
|
||||||
|
emit_pep_category(
|
||||||
|
category="Accepted PEPs (accepted; may not be implemented yet)",
|
||||||
|
anchor="by-category-accepted",
|
||||||
|
peps=accepted,
|
||||||
|
output=output,
|
||||||
|
)
|
||||||
|
emit_pep_category(
|
||||||
|
category="Open PEPs (under consideration)",
|
||||||
|
anchor="by-category-open",
|
||||||
|
peps=open_,
|
||||||
|
output=output,
|
||||||
|
)
|
||||||
|
emit_pep_category(
|
||||||
|
category="Finished PEPs (done, with a stable interface)",
|
||||||
|
anchor="by-category-finished",
|
||||||
|
peps=finished,
|
||||||
|
output=output,
|
||||||
|
)
|
||||||
|
emit_pep_category(
|
||||||
|
category="Historical Meta-PEPs and Informational PEPs",
|
||||||
|
anchor="by-category-historical",
|
||||||
|
peps=historical,
|
||||||
|
output=output,
|
||||||
|
)
|
||||||
|
emit_pep_category(
|
||||||
|
category="Deferred PEPs (postponed pending further research or updates)",
|
||||||
|
anchor="by-category-deferred",
|
||||||
|
peps=deferred,
|
||||||
|
output=output,
|
||||||
|
)
|
||||||
|
emit_pep_category(
|
||||||
|
category="Abandoned, Withdrawn, and Rejected PEPs",
|
||||||
|
anchor="by-category-abandoned",
|
||||||
|
peps=dead,
|
||||||
|
output=output,
|
||||||
|
)
|
||||||
print(file=output)
|
print(file=output)
|
||||||
print(u" Meta-PEPs (PEPs about PEPs or Processes)", file=output)
|
# PEPs by number
|
||||||
print(file=output)
|
emit_title("Numerical Index", "by-pep-number", output)
|
||||||
for pep in meta:
|
emit_column_headers(output)
|
||||||
print(constants.text_type(pep), file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(u" Other Informational PEPs", file=output)
|
|
||||||
print(file=output)
|
|
||||||
for pep in info:
|
|
||||||
print(constants.text_type(pep), file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(u" Provisional PEPs (provisionally accepted; interface may still change)",
|
|
||||||
file=output)
|
|
||||||
print(file=output)
|
|
||||||
for pep in provisional:
|
|
||||||
print(constants.text_type(pep), file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(u" Accepted PEPs (accepted; may not be implemented yet)", file=output)
|
|
||||||
print(file=output)
|
|
||||||
for pep in accepted:
|
|
||||||
print(constants.text_type(pep), file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(u" Open PEPs (under consideration)", file=output)
|
|
||||||
print(file=output)
|
|
||||||
for pep in open_:
|
|
||||||
print(constants.text_type(pep), file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(u" Finished PEPs (done, with a stable interface)", file=output)
|
|
||||||
print(file=output)
|
|
||||||
for pep in finished:
|
|
||||||
print(constants.text_type(pep), file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(u" Historical Meta-PEPs and Informational PEPs", file=output)
|
|
||||||
print(file=output)
|
|
||||||
for pep in historical:
|
|
||||||
print(constants.text_type(pep), file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(u" Deferred PEPs", file=output)
|
|
||||||
print(file=output)
|
|
||||||
for pep in deferred:
|
|
||||||
print(constants.text_type(pep), file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(u" Abandoned, Withdrawn, and Rejected PEPs", file=output)
|
|
||||||
print(file=output)
|
|
||||||
for pep in dead:
|
|
||||||
print(constants.text_type(pep), file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(file=output)
|
|
||||||
print(u"Numerical Index", file=output)
|
|
||||||
print(file=output)
|
|
||||||
write_column_headers(output)
|
|
||||||
prev_pep = 0
|
prev_pep = 0
|
||||||
for pep in peps:
|
for pep in peps:
|
||||||
if pep.number - prev_pep > 1:
|
if pep.number - prev_pep > 1:
|
||||||
print(file=output)
|
print(file=output)
|
||||||
print(constants.text_type(pep), file=output)
|
print(constants.text_type(pep), file=output)
|
||||||
prev_pep = pep.number
|
prev_pep = pep.number
|
||||||
|
print(constants.table_separator, file=output)
|
||||||
print(file=output)
|
print(file=output)
|
||||||
print(file=output)
|
# Reserved PEP numbers
|
||||||
print(u'Reserved PEP Numbers', file=output)
|
emit_title('Reserved PEP Numbers', "reserved", output)
|
||||||
print(file=output)
|
emit_column_headers(output)
|
||||||
write_column_headers(output)
|
|
||||||
for number, claimants in sorted(RESERVED):
|
for number, claimants in sorted(RESERVED):
|
||||||
print(constants.column_format % {
|
print(constants.column_format % {
|
||||||
'type': '',
|
'type': '.',
|
||||||
'status': '',
|
'status': '.',
|
||||||
'number': number,
|
'number': number,
|
||||||
'title': 'RESERVED',
|
'title': 'RESERVED',
|
||||||
'authors': claimants,
|
'authors': claimants,
|
||||||
}, file=output)
|
}, file=output)
|
||||||
|
print(constants.table_separator, file=output)
|
||||||
print(file=output)
|
print(file=output)
|
||||||
print(file=output)
|
# PEP types key
|
||||||
print(u"Key", file=output)
|
emit_title("PEP Types Key", "type-key", output)
|
||||||
print(file=output)
|
for type_ in sorted(PEP.type_values):
|
||||||
for type_ in PEP.type_values:
|
|
||||||
print(u" %s - %s PEP" % (type_[0], type_), file=output)
|
print(u" %s - %s PEP" % (type_[0], type_), file=output)
|
||||||
|
print(file=output)
|
||||||
print(file=output)
|
print(file=output)
|
||||||
for status in PEP.status_values:
|
# PEP status key
|
||||||
print(u" %s - %s proposal" % (status[0], status), file=output)
|
emit_title("PEP Status Key", "status-key", output)
|
||||||
|
for status in sorted(PEP.status_values):
|
||||||
|
# Draft PEPs have no status displayed, Active shares a key with Accepted
|
||||||
|
if status in ("Active", "Draft"):
|
||||||
|
continue
|
||||||
|
if status == "Accepted":
|
||||||
|
msg = " A - Accepted (Standards Track only) or Active proposal"
|
||||||
|
else:
|
||||||
|
msg = " {status[0]} - {status} proposal".format(status=status)
|
||||||
|
print(msg, file=output)
|
||||||
|
print(file=output)
|
||||||
|
|
||||||
print(file=output)
|
print(file=output)
|
||||||
print(file=output)
|
# PEP owners
|
||||||
print(u"Owners", file=output)
|
emit_title("Authors/Owners", "authors", output)
|
||||||
print(file=output)
|
|
||||||
authors_dict = verify_email_addresses(peps)
|
authors_dict = verify_email_addresses(peps)
|
||||||
max_name = max(authors_dict.keys(), key=normalized_last_first)
|
max_name = max(authors_dict.keys(), key=normalized_last_first)
|
||||||
max_name_len = len(max_name.last_first)
|
max_name_len = len(max_name.last_first)
|
||||||
print(u" %s %s" % ('name'.ljust(max_name_len), 'email address'), file=output)
|
author_table_separator = "="*max_name_len + " " + "="*len("email address")
|
||||||
print(u" %s %s" % ((len('name')*'-').ljust(max_name_len),
|
print(author_table_separator, file=output)
|
||||||
len('email address')*'-'), file=output)
|
_author_header_fmt = "{name:{max_name_len}} Email Address"
|
||||||
|
print(_author_header_fmt.format(name="Name", max_name_len=max_name_len), file=output)
|
||||||
|
print(author_table_separator, file=output)
|
||||||
sorted_authors = sort_authors(authors_dict)
|
sorted_authors = sort_authors(authors_dict)
|
||||||
|
_author_fmt = "{author.last_first:{max_name_len}} {author_email}"
|
||||||
for author in sorted_authors:
|
for author in sorted_authors:
|
||||||
# Use the email from authors_dict instead of the one from 'author' as
|
# Use the email from authors_dict instead of the one from 'author' as
|
||||||
# the author instance may have an empty email.
|
# the author instance may have an empty email.
|
||||||
print((u" %s %s" %
|
_entry = _author_fmt.format(
|
||||||
(author.last_first.ljust(max_name_len), authors_dict[author])), file=output)
|
author=author,
|
||||||
|
author_email=authors_dict[author],
|
||||||
|
max_name_len=max_name_len,
|
||||||
|
)
|
||||||
|
print(_entry, file=output)
|
||||||
|
print(author_table_separator, file=output)
|
||||||
print(file=output)
|
print(file=output)
|
||||||
print(file=output)
|
print(file=output)
|
||||||
print(u"References", file=output)
|
# References for introduction footnotes
|
||||||
print(file=output)
|
emit_title("References", "references", output)
|
||||||
print(constants.references, file=output)
|
print(constants.references, file=output)
|
||||||
print(constants.footer, file=output)
|
print(constants.footer, file=output)
|
||||||
|
|
|
@ -99,11 +99,11 @@ class Author(object):
|
||||||
name_parts = self.last.split()
|
name_parts = self.last.split()
|
||||||
for index, part in enumerate(name_parts):
|
for index, part in enumerate(name_parts):
|
||||||
if part[0].isupper():
|
if part[0].isupper():
|
||||||
|
base = u' '.join(name_parts[index:]).lower()
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise ValueError("last name missing a capital letter: %r"
|
# If no capitals, use the whole string
|
||||||
% name_parts)
|
base = self.last.lower()
|
||||||
base = u' '.join(name_parts[index:]).lower()
|
|
||||||
return unicodedata.normalize('NFKD', base).encode('ASCII', 'ignore')
|
return unicodedata.normalize('NFKD', base).encode('ASCII', 'ignore')
|
||||||
|
|
||||||
def _last_name(self, full_name):
|
def _last_name(self, full_name):
|
||||||
|
|
Loading…
Reference in New Issue