The Internet Archive discovers and captures web pages through many different web crawls.
At any given time several distinct crawls are running, some for months, and some every day or longer.
View the web archive through the Wayback Machine.
The Wayback Machine - https://web.archive.org/web/20161205231808/https://tools.ietf.org/tools/rfcmarkup/code
#!/usr/bin/env python# -*- python -*-## Add HTML markup and links to internet-drafts and RFCs## -----------------------------------------------------------------## Copyright 2002 Henrik Levkowetz## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA## -----------------------------------------------------------------## The current version of GPL is at http://www.gnu.org/licenses/gpl.txt## -----------------------------------------------------------------## The purpose of this program is to fetch a text document# indicated by a URL, and add markup so that any references to# interet-drafts or RFCs are changed into hyperlinks, for easier# browsing.## It is called as:## .../cgi-bin/markup.cgi?url=http://www.ietf.org/internet-drafts/draft-something-or-other-00.txt##import cgi, os, sys, urllib, re, string, cgitb
""" TODO: * Handle IEN-nnnn references * Refactor into get_args() markup_top() markup_body() markup_refs() which in turn use fix_urls() fix_rfcs() fix_drafts() fix_refref() fix_refdef() ..."""
version ="1.96"
cgitb.enable()
args = {}
args["bisdraft"] =""
args["dcmeta"] =""
args["dcmetaprofile"] =""
args["diffmenu"] =""
args["doccolor"] =""
args["docinfo"] =True
args["draft"] =""
args["errata"] =""
args["favicon"] =""
args["iprmenu"] =""
args["erratamenu"] =""
args["nitsmenu"] =""
args["obsolete"] =""
args["overflow"] =""
args["padding"] =""
args["plaintext"] =""
args["script"] ="rfcmarkup"
args["status"] =""
args["title"] ="rfcmarkup.cgi"
args["tracker"] =""
args["updated"] =""
args["version"] = version
args["wgmenu"] =""
args["emailmenu"] =""
args["doc"] =""
args["extrastyle"] =""
args["htmllink"] =""
args["style"] =""" <style type="text/css"> body { margin: 0px 8px; font-size: 1em; } h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { font-weight: bold; line-height: 0pt; display: inline; white-space: pre; font-family: monospace; font-size: 1em; font-weight: bold; } pre { font-size: 1em; margin-top: 0px; margin-bottom: 0px; } .pre { white-space: pre; font-family: monospace; } .header{ font-weight: bold; } .newpage { page-break-before: always; } .invisible { text-decoration: none; color: white; } @media print { body { font-size: 10.5pt; } h1, h2, h3, h4, h5, h6 { font-size: 10.5pt; } a:link, a:visited { color: inherit; text-decoration: none; } .noprint { display: none; } } @media screen { .grey, .grey a:link, .grey a:visited { color: #777; } .docinfo { background-color: #EEE; } .top { border-top: 7px solid #EEE; } .bgwhite { background-color: white; } .bgred { background-color: #F44; } .bggrey { background-color: #666; } .bgbrown { background-color: #840; } .bgorange { background-color: #FA0; } .bgyellow { background-color: #EE0; } .bgmagenta{ background-color: #F4F; } .bgblue { background-color: #66F; } .bgcyan { background-color: #4DD; } .bggreen { background-color: #4F4; } .legend { font-size: 90%; } .cplate { font-size: 70%; border: solid grey 1px; } } </style> <!--[if IE]> <style> body { font-size: 13px; margin: 10px 10px; } </style> <![endif]-->"""
status2style = {"BEST CURRENT PRACTICE":"bgmagenta","DRAFT STANDARD":"bgcyan","EXPERIMENTAL":"bgyellow","HISTORIC":"bggrey","INFORMATIONAL":"bgorange","PROPOSED STANDARD":"bgblue","STANDARD":"bggreen",}
usagetext ="""NAME %(script)s - add HTML markup and links to internet-drafts and RFCsSYNOPSIS http://example.com/cgi-bin/%(script)s?url=http://example.org/document.txtDESCRIPTION This program is a cgi-bin script which adds html link markup on the fly to IETF text-format documents - i.e. RFCs, drafts and other text documents which contain references to RFCs and drafts. The script is written in Python, so the http server on which you run it must have Python installed. You can download Python from http://www.python.org. The script has been verified to work with Python 2.2 and later. It may be called by either http POST or GET, and the relevant field names which may be provided are as follows:OPTIONS rfc=number Specify the number of an RFC to fetch and mark up. draft=draft-name Specify the name of an internet-draft to fetch and mark up doc=rfcnum-or-draftname %(script)s will guess which document is wanted based on the name or number given url=some-general-url Specify an url to fetch and mark up. If the URL does not have a scheme identifier, or if it has file: as its scheme identifier, this opens a local file; otherwise it opens a socket to a server somewhere on the network. Either rfc, draft, doc or url must be provided. Example: http://www.levkowetz.com/ietf/%(script)s?rfc=3344 will return RFC 3344 with added link markup. repository=repository-path Specify a nonstandard repository to fetch documents from. By default, RFCs or drafts are read from the repository at http://www.ietf.org/. repository-path may be an url or a path local to the server on which the script is running. The last alternative is useful when running the script under a http server on a local machine, when you also have an RFC and draft repository on the same machine. This option assumes that there is one rfc/ directory and one internet-drafts/ directory under the given repository path, whether it is an url or a local path. Example: http://localhost/cgi-bin/%(script)s?rfc=3344&repository=/usr/local/share/ietf will fetch RFCs from /usr/local/share/ietf/rfc/ on the server on which the script is running.COPYRIGHT Copyright 2002 Henrik Levkowetz This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should be able to retrieve a copy of the GNU General Public License from http://www.gnu.org/licenses/gpl.txt; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USAMAINTAINER %(script)s is maintained by Henrik Levkowetz, <henrik@levkowetz.com>. The latest version of this script can be retrieved from http://tools.ietf.org/tools/rfcmarkup."""% args
defprelude(static=False):ifint(args.get("header","1")):if os.environ.get("GATEWAY_INTERFACE","")and not static:print"Content-type: text/html; charset=utf-8\nCache-Control: max-age=86400\n"
sys.stdout.write("""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head %(dcmetaprofile)s> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="robots" content="%(robots)s" /> <meta name="creator" content="%(script)s version %(version)s" /> %(dcmeta)s <link rel="icon" href="%(favicon)s" type="image/png" /> <link rel="shortcut icon" href="%(favicon)s" type="image/png" /> <title>%(title)s</title> %(extrastyle)s %(style)s <script type="text/javascript"><!-- function addHeaderTags() { var spans = document.getElementsByTagName("span"); for (var i=0; i < spans.length; i++) { var elem = spans[i]; if (elem) { var level = elem.getAttribute("class"); if (level == "h1" || level == "h2" || level == "h3" || level == "h4" || level == "h5" || level == "h6") { elem.innerHTML = "<"+level+">"+elem.innerHTML+"</"+level+">"; } } } } var legend_html = "Colour legend:<br /> \ <table> \ <tr><td>Unknown:</td> <td><span class='cplate bgwhite'> </span></td></tr> \ <tr><td>Draft:</td> <td><span class='cplate bgred'> </span></td></tr> \ <tr><td>Informational:</td> <td><span class='cplate bgorange'> </span></td></tr> \ <tr><td>Experimental:</td> <td><span class='cplate bgyellow'> </span></td></tr> \ <tr><td>Best Common Practice:</td><td><span class='cplate bgmagenta'> </span></td></tr> \ <tr><td>Proposed Standard:</td><td><span class='cplate bgblue'> </span></td></tr> \ <tr><td>Draft Standard:</td> <td><span class='cplate bgcyan'> </span></td></tr> \ <tr><td>Standard:</td> <td><span class='cplate bggreen'> </span></td></tr> \ <tr><td>Historic:</td> <td><span class='cplate bggrey'> </span></td></tr> \ <tr><td>Obsolete:</td> <td><span class='cplate bgbrown'> </span></td></tr> \ </table>"; function showElem(id) { var elem = document.getElementById(id); elem.innerHTML = eval(id+"_html"); elem.style.visibility='visible'; } function hideElem(id) { var elem = document.getElementById(id); elem.style.visibility='hidden'; elem.innerHTML = ""; } // --> </script></head><body onload="addHeaderTags()"> <div style="height: 13px;"> <div onmouseover="this.style.cursor='pointer';" onclick="showElem('legend');" onmouseout="hideElem('legend')" style="height: 6px; position: absolute;" class="pre noprint docinfo %(doccolor)s" title="Click for colour legend." > </div> <div id="legend" class="docinfo noprint pre legend" style="position:absolute; top: 4px; left: 4ex; visibility:hidden; background-color: white; padding: 4px 9px 5px 7px; border: solid #345 1px; " onmouseover="showElem('legend');" onmouseout="hideElem('legend');"> </div> </div>"""% args)else:print"""<html><body> <!-- %(script)s version %(version)s --> %(style)s<pre>"""% args
topmenu ="""<span class="pre noprint docinfo top">[<a href="../html/" title="Document search and retrieval page">Docs</a>] [<a href="%(plaintext)s" title="Plaintext version of this document">txt</a>|<a href="/pdf/%(doc)s" title="PDF version of this document">pdf</a>%(htmllink)s]%(draft)s%(tracker)s%(wgmenu)s%(emailmenu)s%(diffmenu)s%(nitsmenu)s%(iprmenu)s%(erratamenu)s%(padding)s</span><br />"""#wgmenu = """ [<a href="../wg/%(wg)s" title="The working group handling this#document">WG</a>] [<a href="../wg/%(wg)s/%(base)s" title="The WG docment page for this document">Doc Info</a>]"""
wgmenu =""" [<a href="../wg/%(wg)s" title="The working group handling this document">WG</a>]"""
emailmenu =""" [<a href="mailto:%(base)s@tools.ietf.org?subject=%(base)s%%20" title="Send email to the document authors">Email</a>]"""
diffmenu =""" [<a href="/rfcdiff?difftype=--hwdiff&url2=%(doc)s" title="Inline diff (wdiff)">Diff1</a>] [<a href="/rfcdiff?url2=%(doc)s" title="Side-by-side diff">Diff2</a>]"""
nitsmenu =""" [<a href="/idnits?url=http://tools.ietf.org/id/%(doc)s" title="Run an idnits check of this document">Nits</a>]"""
draftiprmenu =""" [<a href="https://datatracker.ietf.org/ipr/search/?option=document_search&document_search=%(base)s" title="IPR disclosures related to this document">IPR</a>]"""
rfciprmenu =""" [<a href="https://datatracker.ietf.org/ipr/search/?option=rfc_search&rfc_search=%(rfc)s" title="IPR disclosures related to this document">IPR</a>]"""
htmllink ="""|<a href="/id/%(draftname)s.html" title="HTML version of this document, from XML2RFC">html</a>"""
docinfo ="""<span class="pre noprint docinfo"> </span><br /><span class="pre noprint docinfo">%(obsolete)-51s%(status)21s</span><br /><span class="pre noprint docinfo">%(updated)-60s%(errata)12s</span><br /><pre>"""
nomenu ="""<pre>"""
statuslen =len("BEST CURRENT PRACTICE")# 21
erratalen =len("Errata Exist")# 12defpostlude():ifint(args.get("blurb","1")):print"""</pre><br /><span class="noprint"><small><small>Html markup produced by rfcmarkup %(version)s, available from<a href="http://tools.ietf.org/tools/rfcmarkup/">http://tools.ietf.org/tools/rfcmarkup/</a></small></small></span></body></html>"""% args
else:print"</pre></body></html>"defversion():prelude()print"%(script)s version %(version)s"% args
postlude()defusage():print usagetext
defmarkup():global args
# sys.stderr = sys.stdout
extra =""
bcp =None
std =None
rfc =None
wgname =None
draftname =None
charter =None
info = {}
attribs = {}
fields = cgi.FieldStorage()for key in fields.keys():
attribs[key] = fields[key].value
script = os.environ.get("SCRIPT_NAME", sys.argv[0])if fields.has_key("info"):
info = fields["info"].value
if(info=="usage"):usage()if(info=="version"):version()returnif fields.has_key("--info"):
info = fields["--info"].value
if(info=="usage"):print usagetext
if(info=="version"):print"%(script)s version %(version)s"% args
returnif fields.has_key("repository"):
rfcs = fields["repository"].value +"/rfc"
ids = fields["repository"].value +"/internet-drafts"
extra = extra +"repository=%s&"% fields["repository"].value
else:if os.path.exists("/home/ietf/rfc"):
rfcs ="file:///home/ietf/rfc"else:
rfcs ="http://tools.ietf.org/rfc"if os.path.exists("/home/ietf/id"):
ids ="file:///home/ietf/id"else:
ids ="http://tools.ietf.org/id"if fields.has_key("rfc-repository"):
rfcs = fields["rfc-repository"].value
extra = extra +"rfc-repository=%s&"% fields["rfc-repository"].value
if fields.has_key("id-repository"):
ids = fields["id-repository"].value
extra = extra +"id-repository=%s&"% fields["id-repository"].value
if fields.has_key("header"):
args["header"] = fields["header"].value
if fields.has_key("blurb"):
args["blurb"] = fields["blurb"].value
if fields.has_key("style"):
args["style"] = fields["style"].value
if fields.has_key("docinfo"):
args["docinfo"] =eval(fields["docinfo"].value)if fields.has_key("robots"):
args["robots"] = fields["robots"].value
else:
args["robots"] ="index,nofollow"if fields.has_key("staticpath"):
optstatic = fields["staticpath"].value =="true"
args["robots"] ="index,follow"else:
optstatic =Falseif fields.has_key("topmenu"):
optmenu = fields["topmenu"].value =="true"#extra = extra + "topmenu=%s&" % fields["topmenu"].valueelse:
optmenu =Falseif fields.has_key("lineoffset"):
optlineoffs =int(fields["lineoffset"].value)#extra = extra + "topmenu=%s&" % fields["topmenu"].valueelse:
optlineoffs =0# Handle document information.if fields.has_key("draft"):
url ="%s/%s"% (ids, fields["draft"].value)
args["title"] = fields["draft"].value[6:].split(".")[0]# if not url[-4:] == ".txt":# url = url + ".txt"elif fields.has_key("rfc"):
rfc = fields["rfc"].value
url ="%s/rfc%s.txt"% (rfcs, rfc)
args["title"] ="rfc "+fields["rfc"].value
args["doc"] ="rfc"+rfc
elif fields.has_key("bcp"):
bcp = fields["bcp"].value
url ="%s/bcp/bcp%s.txt"% (rfcs, bcp)
args["title"] ="bcp "+fields["bcp"].value
args["doc"] ="bcp"+bcp
elif fields.has_key("fyi"):
fyi = fields["fyi"].value
url ="%s/fyi/fyi%s.txt"% (rfcs, fyi)
args["title"] ="fyi "+fields["fyi"].value
args["doc"] ="fyi"+fyi
elif fields.has_key("std"):
std = fields["std"].value
url ="%s/std/std%s.txt"% (rfcs, std)
args["title"] ="std "+fields["std"].value
args["doc"] ="std"+std
elif fields.has_key("url"):
url = fields["url"].value
if not re.match("^(http|https|ftp|file)", url):
url ="http://%s%s/%s"%( os.environ.get("SERVER_NAME","ietf.levkowetz.com"), os.path.dirname(script), url)
args["title"] = os.path.basename(fields["url"].value)elif fields.has_key("doc")or os.environ.get("PATH_INFO","/") !="/":if fields.has_key("doc"):
doc = fields["doc"].value
else:
doc = os.environ.get("PATH_INFO","/")[1:]# Remove extensionif doc.rfind(".") >0:
doc = doc[:doc.rfind(".")]if re.match("^[0-9]+$", doc):
rfc = doc
url ="file:///home/ietf/rfc/rfc%s.txt"% doc
title ="RFC "+ rfc
args["doc"] ="rfc"+rfc
elif re.match("rfc[0-9]+$", doc):
rfc = doc[3:]
url ="%s/%s.txt"% (rfcs, doc)
title ="RFC "+ rfc
args["doc"] ="rfc"+rfc
elif re.match("^bcp[0-9]+$", doc):
url ="%s/bcp/%s.txt"% (rfcs, doc)
title ="BCP "+ doc[3:]
args["doc"] ="bcp"+doc[3:]elif re.match("^fyi[0-9]+$", doc):
url ="%s/fyi/%s.txt"% (rfcs, doc)
title ="FYI "+ doc[3:]
args["doc"] ="fyi"+doc[3:]elif re.match("^std[0-9]+$", doc):
url ="%s/std/%s.txt"% (rfcs, doc)
title ="STD "+ doc[3:]
args["doc"] ="std"+doc[3:]elif re.match("^ion-.+$", doc):
url ="file:///home/ietf/ion/approved/%s.txt"% doc
title ="ION: "+ doc
args["doc"] = doc
elif re.match("^charter-.+$", doc):
url ="file:///www/tools.ietf.org/charter/%s.txt"% doc
title = doc.split(".")[0]
args["doc"] = doc
charter = doc
elif re.match("draft-[0-9a-z.*-]+$", doc):if not re.match(".*\..+", doc):
doc = doc +".txt"
url ="http://tools.ietf.org/id/%s"% doc
title = doc.split(".")[0]
draftparts = re.match("draft-([0-9a-z]+)-(krb-wg|[0-9a-z]+)-([0-9a-z.*-]+)$", doc)if draftparts and draftparts.group(1) =="ietf":
wgname = draftparts.group(2)
args["wg"] = wgname
args["base"] = os.path.splitext(doc)[0][:-3]
draftname = doc
args["doc"] = doc
else:
url ="your document ('%s')."% doc
title =""
args["title"] = title
elif script =="rfcmarkup":usage()#print "<pre>"#print fields#print os.environ#print "</pre>"returnelse:prelude()print"""</pre> <p> <big><b>Add HTML markup to a document:</b></big> </p> <p> Please provide a document number, draft name or URL: </p> <p> <form action="%s"> <table> <tr><td>RFC (number only): </td><td><input type="text" name="rfc" /></td></tr> <tr><td>Draft: (name starting with <tt>draft-</tt>): </td><td><input type="text" name="draft" /></td></tr> <tr><td>URL (any text document available through http or ftp): </td><td><input type="text" name="url" /></td></tr> <tr><td> </td><td><input type="Submit" value="Submit"/></td></tr> </table> </form> </p> </body> </html> """% script
returnif fields.has_key("title"):
args["title"] = fields["title"].value
if fields.has_key("extrastyle"):
args["extrastyle"] ="<style>"+fields["extrastyle"].value+"</style>"
tags = []if fields.has_key("comments"):iftype(fields["comments"])istype([]):for item in fields["comments"]: tags.append(item.value)else:
tags.append(fields["comments"].value)
colors = []if fields.has_key("color"):iftype(fields["color"])istype([]):for item in fields["color"]: colors.append(item.value)else:
colors.append(untaint(fields["color"].value))else:
colors = ["#F00","#0A0","#00C","#880","#088","#808", ]if url.startswith("file:///home/ietf/"):
start =len("file:///home/ietf/") -1
args["plaintext"] = url[start:]else:
args["plaintext"] = url
# Get the raw text of the source pagetry:
f = urllib.urlopen(url)
data = f.read()
f.close()except:prelude();print"<h3> Sorry, couldn't find %s</h3>"% os.path.basename(url)
sys.exit(0)deffiletext(path):if os.path.isfile(path):file=open(path)
text =file.read()file.close()return text.strip()else:return""deflistdir(path, pattern):
dirlist = os.listdir(path)
files = [ x for x in dirlist if re.match(pattern, x) ]
files.sort()return files
defstateinfo(fullname):
name = fullname
if name.endswith(".txt"):
name = name[:-4]if re.search("-[0-9][0-9]$", name):
name = name[:-3]
info =filetext("/www/tools.ietf.org/draft/%s/now"% (name))
attribs = {}if info:
first, rest = info.split(None,1)if first.startswith("19")or first.startswith("20"):
attribs["timestamp"] = first
first, rest = rest.split(None,1)if first.startswith("draft-"):
attribs["document"] = first
attriblist = re.findall("([A-Za-z]+='[^']+')", info)for attrib in attriblist:try:
attr, value = attrib.split("=")
value = value[1:-1]if";"in value:
value = value.rsplit(";",1)[0]
value =eval("'"+value+"'")
attribs[attr] = value
except:passelse:try:import idauthors
if not fullname.endswith(".txt"):
fullname = fullname +".txt"
attribs = idauthors.getmeta(fullname)or{}exceptException:passreturn attribs
defsetdcmeta(attribs, args):
metatext ='<link rel="schema.DC" href="http://purl.org/dc/elements/1.1/" />\n'
metaval = {}
metatags = [("doctitle","DC.Title"),("docauthors","DC.Creator"),("docsubmitted","DC.Date.Issued"),("docpublished","DC.Date.Issued"),# overrides submission date("docabstract","DC.Description.Abstract"),("document","DC.Identifier"),("docrfcnum","DC.Identifier"),# overides draft id("docreplaces","DC.Relation.Replaces"),("docobsoletes","DC.Relation.Replaces"),# overrides draft replacement]
listtags = ["DC.Creator","DC.Relation.Replaces", ]for key, tag in metatags:if key in attribs:if key =="document":
val ="urn:ietf:id:%s"% attribs[key][6:]elif key =="docrfcnum":
val ="urn:ietf:rfc:%s"% attribs[key]else:
val = attribs[key]or""
metaval[tag] = cgi.escape(val)for tag, val in metaval.items():
val = val.replace(r"\\n"," ")if tag in listtags and","in val:
items = val.split(",")if tag =="DC.Creator":for i inrange(len(items)):
item = items[i]
parts = item.split()if parts:if"@"in parts[-1]:
parts = parts[:-1]
items[i] =" ".join(parts)
items =list(set(items))for item in items:
parts = item.split()if parts:# emit with family name first, then comma and given name or initials
metatext +='<meta name="%s" content="%s, %s" />\n'% (tag, parts[-1]," ".join(parts[:-1]))else:for item in items:
metatext +='<meta name="%s" content="%s" />\n'% (tag, item.strip())else:
metatext +='<meta name="%s" content="%s" />\n'% (tag, val)
args["dcmeta"] = metatext
args["dcmetaprofile"] ='profile="http://dublincore.org/documents/2008/08/04/dc-html/"'return args
# Helper function to generate left-side metainformation (list of RFCs)defleftmeta(docname, tag, prefix, rightlen):
line =""
info =filetext("/home/ietf/rfc/meta/%s.%s"% (docname, tag))if info:
line = prefix
leftlen =len(prefix)
rfclen =len(" 0000,")
count =0
maxcount = (72- leftlen -max(rightlen,erratalen,statuslen))/rfclen
for rfc in info.split():
rfcnum = rfc[3:]if count:
line = line +","if(count % maxcount) ==0:
line = line +" "*(72-leftlen-rfclen*maxcount) +"\n"+" "*leftlen
count +=1if optstatic:
line = line +""" <a href=\"./rfc%s\">%s</a>"""% (rfcnum, rfcnum)else:
line = line +""" <a href=\"%s/%s\">%s</a>"""% (script, rfcnum, rfcnum)
line = line +" "*(72-leftlen-rightlen-((count-1)%maxcount+1)*rfclen+1)# +1 for the missing comma after the last rfcnumreturn line, info
defchartermeta(charter, prefix, rightlen, attribs):
name = re.sub("-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9](\.txt)?$","", charter)
line =""
files =listdir("/www/tools.ietf.org/charter/", name+"-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\.txt$")
versions = [file[-14:-4]forfilein files ]if versions:
line = line + prefix
leftlen =len(prefix)
verlen =len(" 2000-01-01")
count =0
nextdoclen =0
maxcount = (72- leftlen - rightlen)/verlen
for ver in versions:if count:#line = line + ","if(count % maxcount) ==0:
line = line +" "*(72-leftlen-verlen*maxcount) +"\n"+" "*leftlen
count +=1if optstatic:
line = line +""" <a href=\"./%s-%s\">%s</a>"""% (name, ver, ver)else:
line = line +""" <a href=\"%s/%s-%s\">%s</a>"""% (script, name, ver, ver)
line = line +" "*(50-leftlen-rightlen-nextdoclen-(count%maxcount)*verlen+1)# +1 for the missing comma after the last rfcnumreturn line
defdraftmeta(draftname, prefix, rightlen, attribs):
name = draftname[:-3]
rev = draftname[-2:]
line =""
rfc =filetext("/home/ietf/rfc/meta/%s.rfcnum"% (name,))
versions =filetext("/www/tools.ietf.org/draft/%s/versions"% (name,))if versions:if not rev in versions:
versions +=" "+ rev
attribs["docversions"] =", ".join(versions.split())
line = line + prefix
leftlen =len(prefix)
verlen =len(" 00")
count =0
nextdoclen =0
maxcount = (47- leftlen - rightlen)/verlen
prev =Noneif"docreplaces"in attribs:
prev = attribs["docreplaces"]
pname = prev
else:
match = re.match(".*-((rfc)?[0-9][0-9][0-9]+)bis(-.*|$)", name)if match:
prev = match.group(1)
pname = prev
if pname.startswith("rfc"):
pname = pname[3:]
pname ="RFC "+ pname
if prev:if optstatic:
line = line +""" (<a href="./%s" title="Precursor">%s</a>)"""% (prev, pname)else:
line = line +""" (<a href="%s/%s" title="Precursor">%s</a>)"""% (script, prev, pname)
prevlen =len(" (%s)"% pname)
count = (prevlen + verlen-1) // verlen
line = line +" "* (count*verlen - prevlen)if count >= maxcount:
line = line +" "*(72-leftlen-verlen*count) +"\n"+" "*leftlen
count =0for ver in versions.split():if count:#line = line + ","if(count % maxcount) ==0:
line = line +" "*(72-leftlen-verlen*maxcount) +"\n"+" "*leftlen
count +=1if optstatic:
line = line +""" <a href=\"./%s-%s\">%s</a>"""% (name, ver, ver)else:
line = line +""" <a href=\"%s/%s-%s\">%s</a>"""% (script, name, ver, ver)if rfc:
rfcnum = rfc[3:]ifint(rfcnum) >0:if(count % maxcount) ==0:
line = line +" "*(72-leftlen-verlen*maxcount) +"\n"+" "*leftlen
nextdoclen =len(" RFC 0000")if optstatic:
line = line +""" <a href=\"./rfc%s\">RFC %4s</a>"""% (rfcnum, rfcnum)else:
line = line +""" <a href=\"%s/%s\">RFC %4s</a>"""% (script, rfcnum, rfcnum)elif"docreplacement"in attribs:
replacement = attribs["docreplacement"]if replacement and replacement !="0":if(count % maxcount) ==0:
line = line +" "*(72-leftlen-verlen*maxcount) +"\n"+" "*leftlen
nextdoclen =len(replacement)+1if optstatic:
line = line +""" <a href=\"./%s\"title="%s replaces this draft">%s</a>"""% (replacement, replacement, replacement)else:
line = line +""" <a href=\"%s/%s\"title="%s replaces this draft">%s</a>"""% (script, replacement, replacement, replacement)
line = line +" "*(50-leftlen-rightlen-nextdoclen-(count%maxcount)*verlen+1)# +1 for the missing comma after the last rfcnumreturn line
if draftname:
attribs.update(stateinfo(draftname))
args["favicon"] ="/images/id.png"
draftname = draftname.split(".")[0]
args["obsolete"] =draftmeta(draftname,"Versions:",0, attribs)
args["doccolor"] ="bgred"
args["tracker"] =" [<a href='https://datatracker.ietf.org/doc/%s' title='IESG Datatracker information for this document'>Tracker</a>]"% (draftname[:-3])elif charter and optmenu:
args["obsolete"] =chartermeta(charter,"Versions:",0, attribs)elif rfc:
attribs.update(stateinfo("rfc%s"% (rfc)))
args["favicon"] ="/images/rfc.png"iffiletext("/home/ietf/rfc/meta/rfc%s.errata"% rfc):# Errata URL changes around 18 Oct 2007 # args["errata"] = """<a href="http://www.rfc-editor.org/cgi-bin/errataSearch.pl?rfc=%s">Errata</a>""" % rfc
args["errata"] ="<span style='color: #C00;'>Errata Exist</span>"
args["erratamenu"] =""" [<a href="http://www.rfc-editor.org/errata_search.php?rfc=%s">Errata</a>]"""% rfc
args["status"] =filetext("/home/ietf/rfc/meta/rfc%s.status"% rfc)
args["obsolete"], info =leftmeta("rfc%s"%rfc,"obsolete","Obsoleted by:", statuslen)
args["updated"], info =leftmeta("rfc%s"%rfc,"updated","Updated by:", erratalen)if args["obsolete"]:
args["doccolor"] ="bgbrown"else:if args["status"]in status2style:
args["doccolor"] = status2style[args["status"]]else:
args["doccolor"] ="bgwhite"# If there is no obsolete field, use that for Updated# Assumption: the obsoleted by list never has more than 6 rfcs,# but the updated by list may have more.iflen(args["updated"])and notlen(args["obsolete"]):
leftlen =len("Updated by:")
rightlen = statuslen
rfclen =len(" 0000,")
maxcount = (72- leftlen -max(rightlen,erratalen,statuslen))/rfclen
count =min(maxcount,len(info.split()))
updated = args["updated"].split("\n",1)
args["obsolete"] = updated[0]if updated[1:]:
args["updated"] = updated[1]else:
args["updated"] =""# Add padding to make the line 72 spaces wide when renderediflen(info.split()) > maxcount:
args["obsolete"] = args["obsolete"].strip() +" "* (72-leftlen-rightlen-count*rfclen)else:
args["obsolete"] = args["obsolete"].strip() +" "* (72-leftlen-rightlen-count*rfclen+1)# +1 for the missing comma after the last rfcnum
draft =filetext("/home/ietf/rfc/meta/rfc%s.draft"% rfc)if draft:
short = draft
draftmaxlen =29if"errata"in args:
draftmaxlen -=len(" [Errata]")iflen(draft) > draftmaxlen:
short = draft[:draftmaxlen-3] +"..."if optstatic:
args["draft"] = (""" [<a href="%s" title="%s">%s</a>]""") % (draft, draft, short)else:
args["draft"] = (""" [<a href="%s?%sdoc=%s" title="%s">%s</a>]""") % (script, optmenu and"topmenu=true&"or"",draft, draft, short)elif bcp:
args["doccolor"] ="bgmagenta"elif std:
args["doccolor"] ="bggreen"
args =setdcmeta(attribs, args)if f.info().gettype() =="text/html":print"Location: %s\n"% url
# print f.info()# print datareturn# ------------------------------------------------------------------------# Start of markup handling# Convert \r which is not followed or preceded by a \n to \n# (in case this is a mac document)
data = re.sub("([^\n])\r([^\n])","\g<1>\n\g<2>", data)# Strip \r (in case this is a ms format document):
data = string.replace(data,"\r","")# -------------# Normalization# Remove whitespace at the end of lines
data = re.sub("[\t]+\n","\n", data)
data = data.expandtabs()# Remove extra blank lines at the start of the document
data = re.sub("^\n*","", data,1)# Fix up page breaks:# \f should aways be preceeded and followed by \n
data = re.sub("([^\n])\f","\g<1>\n\f", data)
data = re.sub("\f([^\n])","\f\n\g<1>", data)# [Page nn] should be followed by \n\f\n
data = re.sub("(?i)(\[Page [0-9ivxlc]+\])[\n\f\t]*(\n*[^\n\f\t])","\g<1>\n\f\g<2>", data)# Normalize indentation
linestarts = re.findall("(?m)^([ ]*)\S", data);
prefixlen =72for start in linestarts:iflen(start) < prefixlen:
prefixlen =len(start)if prefixlen:
data = re.sub("\n"+(" "*prefixlen),"\n", data)# reference name tag markup
reference = {}
ref_url = {}## Locate the start of the References section as the first reference## definition after the last reference usage## Incomplete 05 Aug 2010 17:05:27##ref_usages = re.findall("(\W)(\[)([-\w.]+)((, ?[-\w.]+)*\])", data)
ref_defs = re.findall("(?sm)^( *\n*)\[([-\w.]+?)\]( +)(.*?)(\n*)$", data)##ref_pos = [ match.start() for match in ref_usages ]##def_pos = [ match.start() for match in ref_defs ]##ref_pos = [ pos for pos in ref_pos if not pos in ref_defs ]##last_ref_pos = ref_pos[-1] if ref_pos else None#sys.stderr.write("ref_defs: %s\n" % repr(ref_defs)) fortuplein ref_defs:
title_match = re.search("(?sm)^(.*?(\"[^\"]+?\").+?|.*?(,[^,]+?,)[^,]+?)$",tuple[3])if title_match:
reftitle = title_match.group(2)or title_match.group(3).strip("[ ,]+")# Get rid of page break information inside the title
reftitle = re.sub("(?s)\n\n\S+.*\n\n","", reftitle)
reftitle = reftitle.replace("'","'")# Quote quotes
reftitle = re.sub("[\n\t]+"," ", reftitle)# Remove newlines and tabs
reference[tuple[1]] = reftitle
url_match = re.search(r"(http|https|ftp)://\S+",tuple[3])if url_match:
ref_url[tuple[1]] = url_match.group(0)# -------------# escape any html significant characters
data = cgi.escape(data);# -------------# Adding markup# Typewriter-style underline:
data = re.sub("_[\b](.)","<u>\g<1></u>", data)# Line number markup goes here# Obsoletes: ... markupdefrfclist_replace(keyword, data):defreplacement(match):
group =list(match.groups(""))
group[3] = re.sub("\d+","""<a href=\"%s?%srfc=\g<0>\">\g<0></a>"""% (script, extra), group[3])if group[8]:
group[8] = re.sub("\d+","""<a href=\"%s?%srfc=\g<0>\">\g<0></a>"""% (script, extra), group[8])else:
group[8] =""return"\n%s%s%s\n%s%s"% (group[0], group[3], group[5], group[7], group[8])
data = re.sub("\n(%s( RFCs| RFC)?: ?( RFCs| RFC)?)(( \d+,| \d+)+)(.*)\n(( *)((\d+, )*(\d+)))*"% keyword, replacement, data,1)return data
data =rfclist_replace("Obsoletes", data)
data =rfclist_replace("Updates", data)
lines = data.splitlines(True)
head ="".join(lines[:28])
rest ="".join(lines[28:])# title markup
head = re.sub("""(?im)(([12][0-9][0-9][0-9]|^Obsoletes.*|^Category: (Standards Track|Informational|Experimental|Best Current Practice)) *\n\n+ +)([A-Z][^\n]+)$""","""\g<1><span class=\"h1\">\g<4></span>""", head,1)
head = re.sub("""(?i)(<span class="h1".+</span>)(\n+)([^<\n]+)\n""","""\g<1>\g<2><span class="h1">\g<3></span>\n""", head,1)
head = re.sub("""(?i)(<span class="h1".+</span>)(\n+)([^<\n]+)\n""","""\g<1>\g<2><span class="h1">\g<3></span>\n""", head,1)if"doctitle"in attribs:
args["title"] = args["title"] +" - "+ attribs["doctitle"]else:for match in re.finditer("""(?i)<span class="h1".*?>(.+?)</span>""", head):if not(match.group(1).startswith("draft-")or match.group(1).startswith("<draft-")):if not" -"in args["title"]:
args["title"] = args["title"] +" -"
args["title"] = args["title"] +" "+ match.group(1)
data = head + rest
# http link markup# link crossing a line. Not permitting ":" after the line break will# result in some URLs broken across lines not being recognized, but# will on the other hand correctly handle a series of URL listed line# by line, one on each line.# Link crossing a line, where the continuation contains '.' or '/'
data = re.sub("(?im)(\s|^|[^=]\"|\()((http|https|ftp)://([:A-Za-z0-9_./@%&?#~=-]+)?)(\n+)([A-Za-z0-9_./@%&?#~=-]+[./][A-Za-z0-9_./@%&?#~=-]+[A-Za-z0-9_/@%&?#~=-])([.,)\"\s]|$)","\g<1><a href=\"\g<2>\g<6>\">\g<2></a>\g<5><a href=\"\g<2>\g<6>\">\g<6></a>\g<7>", data)
data = re.sub("(?im)(<)((http|https|ftp)://([:A-Za-z0-9_./@%&?#~=-]+)?)(\n+)([A-Za-z0-9_./@%&?#~=-]+[A-Za-z0-9_/@%&?#~=-])(>)","\g<1><a href=\"\g<2>\g<6>\">\g<2></a>\g<5><a href=\"\g<2>\g<6>\">\g<6></a>\g<7>", data)# Link crossing a line, where first line ends in '-'
data = re.sub("(?im)(\s|^|[^=]\"|\()((http|https|ftp)://([:A-Za-z0-9_./@%&?#~=-]+)?-)(\n+)([A-Za-z0-9_./@%&?#~=-]+[A-Za-z0-9_/@%&?#~=-])([.,)\"\s]|$)","\g<1><a href=\"\g<2>\g<6>\">\g<2></a>\g<5><a href=\"\g<2>\g<6>\">\g<6></a>\g<7>", data)
data = re.sub("(?im)(<)((http|https|ftp)://([:A-Za-z0-9_./@%&?#~=-]+)?)(\n+)([A-Za-z0-9_./@%&?#~=-]+[A-Za-z0-9_/@%&?#~=-])(>)","\g<1><a href=\"\g<2>\g<6>\">\g<2></a>\g<5><a href=\"\g<2>\g<6>\">\g<6></a>\g<7>", data)# link crossing a line, enclosed in "<" ... ">"
data = re.sub("(?im)<((http|https|ftp)://([:A-Za-z0-9_./@%&?#~=-]+)?)(\n+)([A-Za-z0-9_./@%&?#~=-]+[A-Za-z0-9_/@%&?#~=-])>","<\g<1><a href=\"\g<1>\g<5>\">\g<1></a>\g<4><a href=\"\g<1>\g<5>\">\g<5></a>>", data)
data = re.sub("(?im)(<)((http|https|ftp)://([:A-Za-z0-9_./@%&?#~=-]+)?)(\n+)([A-Za-z0-9_./@%&?#~=-]+[A-Za-z0-9_/@%&?#~=-])(>)","\g<1><a href=\"\g<2>\g<6>\">\g<2></a>\g<5><a href=\"\g<2>\g<6>\">\g<6></a>\g<7>", data)# link on a single line
data = re.sub("(?im)(\s|^|[^=]\"|<|\()((http|https|ftp)://[:A-Za-z0-9_./@%&?#~=-]+[A-Za-z0-9_/@%&?#~=-])([.,)\"\s]|>|$)","\g<1><a href=\"\g<2>\">\g<2></a>\g<4>", data)# undo markup if RFC2606 domain
data = re.sub("""(?i)<a href="[a-z]*?://([a-z0-9_-]+?\.)?example(\.(com|org|net))?(/.*?)?">(.*?)</a>""","\g<5>", data)# draft markup# draft name crossing line break
data = re.sub("([^/#=\?\w-])(draft-([-a-zA-Z0-9]+-)?)(\n+)([-a-zA-Z0-9]+[a-zA-Z0-9](.txt)?)","\g<1><a href=\"%s?%sdraft=\g<2>\g<5>\">\g<2></a>\g<4><a href=\"%s?%sdraft=\g<2>\g<5>\">\g<5></a>"% (script, extra, script, extra), data)# draft name on one line (but don't mess with what we just did above)
data = re.sub("([^/#=\?\w>=-])(draft-[-a-zA-Z0-9]+[a-zA-Z0-9](.txt)?)","\g<1><a href=\"%s?%sdraft=\g<2>\">\g<2></a>"% (script, extra), data)# rfc markup# rfc and number on the same line
data = re.sub("""(?i)([^[/\w-])(rfc([- ]?))([0-9]+)(\W)""","""\g<1><a href=\"%s?%srfc=\g<4>\">\g<2>\g<4></a>\g<5>"""% (script, extra), data)# rfc and number on separate lines
data = re.sub("(?i)([^[/\w-])(rfc([-]?))(\n+)([0-9]+)(\W)","\g<1><a href=\"%s?%srfc=\g<5>\">\g<2></a>\g<4><a href=\"%s?%srfc=\g<5>\">\g<5></a>\g<6>"% (script, extra, script, extra), data)# spelled out Request For Comments markup
data = re.sub("(?i)(\s)(Request\s+For\s+Comments\s+\([^)]+\)\s+)([0-9]+)","\g<1>\g<2><a href=\"%s?%srfc=\g<3>\">\g<3></a>"% (script, extra), data)# bcp markup
data = re.sub("(?i)([^[/\w-])(bcp([- ]?))([0-9]+)(\W)","\g<1><a href=\"%s?%sbcp=\g<4>\">\g<2>\g<4></a>\g<5>"% (script, extra), data)
data = re.sub("(?i)([^[/\w-])(bcp([-]?))(\n+)([0-9]+)(\W)","\g<1><a href=\"%s?%sbcp=\g<5>\">\g<2></a>\g<4><a href=\"%s?%sbcp=\g<5>\">\g<5></a>\g<6>"% (script, extra, script, extra), data)defworkinprogress_replacement(match):
g1 = match.group(1)
g2 = match.group(2)
g3 = match.group(3)# eliminate embedded hyperlinks in text we'll use as anchor text
g4 = match.group(4)
g4 = re.sub("<a.+?>(.+?)</a>","\g<1>", g4)
g4url = urllib.quote_plus(g4)
g5 = match.group(5)return"""%s[<a name=\"ref-%s\"id=\"ref-%s\">%s</a>]%s<a style=\"text-decoration: none\"href='http://www.google.com/search?sitesearch=tools.ietf.org%%2Fhtml%%2F&q=inurl:draft-+%s'>%s</a>%s"""% (g1, g2, g2, g2, g3, g4url, g4, g5)
data = re.sub("(\n*\n*)\[([-\w.]+)\](\s+.*?)(\".+\")(,\s+Work\s+in\s+Progress.)", workinprogress_replacement, data)
data = re.sub("(\n*\n*)\[([-\w.]+)\](\s)","\g<1>[<a name=\"ref-\g<2>\"id=\"ref-\g<2>\">\g<2></a>]\g<3>", data)
data = re.sub("(\n*\n*)\[(RFC [-\w.]+)\](\s)","\g<1>[<a name=\"ref-\g<2>\"id=\"ref-\g<2>\">\g<2></a>]\g<3>", data)
ref_targets = re.findall('<a name="ref-(.*?)"', data)# reference link markupdefreference_replacement(match):
pre = match.group(1)
beg = match.group(2)
tag = match.group(3)
end = match.group(4)
isrfc = re.match("(?i)^rfc[ -]?([0-9]+)$", tag)if isrfc:
rfcnum = isrfc.group(1)if tag in reference:return"""%s%s<a href="%s?%srfc=%s" title='%s'>%s</a>%s"""% (pre, beg, script, extra, rfcnum, cgi.escape(reference[tag]), tag, end)else:return"""%s%s<a href="%s?%srfc=%s">%s</a>%s"""% (pre, beg, script, extra, rfcnum , tag, end)else:if tag in ref_targets:if tag in reference:return"""%s%s<a href="#ref-%s" title='%s'>%s</a>%s"""% (pre, beg, tag, cgi.escape(reference[tag]), tag, end)else:return"""%s%s<a href="#ref-%s">%s</a>%s"""% (pre, beg, tag, tag, end)else:return match.group(0)# Group: 1 2 3 45
data = re.sub("(\W)(\[)([-\w.]+)((, ?[-\w.]+)*\])", reference_replacement, data)
data = re.sub("(\W)(\[)(RFC [0-9]+)((, ?RFC [0-9]+)*\])", reference_replacement, data)while True:
old = data
data = re.sub("(\W)(\[(?:<a.*?>.*?</a>, ?)+)([-\w.]+)((, ?[-\w.]+)*\])", reference_replacement, data)if data == old:breakwhile True:
old = data
data = re.sub("(\W)(\[(?:<a.*?>.*?</a>, ?)+)(RFC [-\w.]+)((, ?RFC [-\w.]+)*\])", reference_replacement, data)if data == old:break# greying out the page headers and footers
data = re.sub("\n(.+\[Page \w+\])\n\f\n(.+)\n","""\n<span class="grey">\g<1></span>\n\f\n<span class="grey">\g<2></span>\n""", data)# contents link markup: section links# 1 2 3 4 5 6 7
data = re.sub("(?m)^(\s*)(\d+(\.\d+)*)(\.?[ ]+)(.*[^ .])( *\. ?\.)(.*[0-9])$","""\g<1><a href="#section-\g<2>">\g<2></a>\g<4>\g<5>\g<6>\g<7>""", data)
data = re.sub("(?m)^(\s*)(Appendix |)([A-Z](\.\d+)*)(\.?[ ]+)(.*[^ .])( *\. ?\.)(.*[0-9])$","""\g<1><a href="#appendix-\g<3>">\g<2>\g<3></a>\g<5>\g<6>\g<7>\g<8>""", data)# page number markup
multidoc_separator ="========================================================================"if re.search(multidoc_separator, data):
parts = re.split(multidoc_separator, data)for i inrange(len(parts)):
parts[i] = re.sub("(?si)(\f)([^\f]*\[Page (\w+)\])","\g<1><a name=\"%(page)s-\g<3>\"id=\"%(page)s-\g<3>\"href=\"#%(page)s-\g<3>\"class=\"invisible\"> </a>\g<2>"%{"page":"page-%s"%(i+1)}, parts[i])
parts[i] = re.sub("(?i)(\. ?\. *)([0-9ivxlc]+)( *\n)","\g<1><a href=\"#%(page)s-\g<2>\">\g<2></a>\g<3>"%{"page":"page-%s"%(i+1)}, parts[i])
data = multidoc_separator.join(parts)else:# page name tag markup
data = re.sub("(?si)(\f)([^\f]*\[Page (\w+)\])","\g<1><a name=\"page-\g<3>\"id=\"page-\g<3>\"href=\"#page-\g<3>\"class=\"invisible\"> </a>\g<2>", data)# contents link markup: page numbers
data = re.sub("(?i)(\. ?\. *)([0-9ivxlc]+)( *\n)","\g<1><a href=\"#page-\g<2>\">\g<2></a>\g<3>", data)# section number tag markupdefsection_anchor_replacement(match):# exclude TOC entries
mstring = match.group(0)if" \. \. "in mstring or"\.\.\."in mstring:return mstring
level =len(re.findall("[^\.]+", match.group(1)))+1if level >6:
level =6return"""<span class="h%s"><a name=\"section-%s\">%s</a>%s</span>"""% (level, match.group(1), match.group(1), match.group(3))
data = re.sub("(?im)^(\d+(\.\d+)*)(\.?[ ].*)$", section_anchor_replacement, data)#data = re.sub("(?i)(\n *\n *)(\d+(\.\d+)*)(\.?[ ].*)", section_replacement, data)# section number link markup
data = re.sub("(?i)(section\s)(\d+(\.\d+)*)","<a href=\"#section-\g<2>\">\g<1>\g<2></a>", data)
data = re.sub("(?i)(section)\n(\s+)(\d+(\.\d+)*)","<a href=\"#section-\g<3>\">\g<1></a>\n\g<2><a href=\"#section-\g<3>\">\g<3></a>", data)while True:
old = data
data = re.sub("(?i)(sections\s(<a.*?>.*?</a>(,\s|\s?-\s?|\sthrough\s|\sor\s|\sto\s|,?\sand\s))*)(\d+(\.\d+)*)","\g<1><a href=\"#section-\g<4>\">\g<4></a>", data)if data == old:break# # section x of draft-y markup# data = re.sub("(?i)<a href=\"[^\"]*\">(section)\s(\d+(\.\d+)*)</a>(\s+(of|in)\s+)<a href=\"[^\"]*\">(draft-[-.a-zA-Z0-9]+[a-zA-Z0-9])</a>", "<a href=\"%s?%surl=%s/rfc\g<7>.txt#section-\g<2>\">\g<1> \g<2>\g<4>\g<6>\g<7></a>" % (script, extra, rfcs), data)# # draft-y, section x markup# data = re.sub("(?i)<a href=\"[^\"]*\">(draft-[-.a-zA-Z0-9]+[a-zA-Z0-9])</a>(,?\s)<a href=\"[^\"]*\">(section)\s(\d+(\.\d+)*)</a>", "<a href=\"%s?%surl=%s/rfc\g<2>.txt#section-\g<5>\">\g<1>\g<2>\g<3>\g<4> \g<5></a>" % (script, extra, rfcs), data)# # [draft-y], section x markup# data = re.sub("(?i)\[<a href=\"[^>\"]+\">(draft-[-.a-zA-Z0-9]+[a-zA-Z0-9])</a>\](,?\s)<a href=\"[^>\"]*\">(section)\s(\d+(\.\d+)*)</a>", "<a href=\"%s?%surl=%s/rfc\g<2>.txt#section-\g<5>\">[\g<1>\g<2>]\g<3>\g<4> \g<5></a>" % (script, extra, rfcs), data)# section x of rfc y markup
data = re.sub("(?i)<a href=\"[^\"]*\"[^>]*>(section)\s(\d+(\.\d+)*)</a>(\s+(of|in)\s+)<a href=\"[^\"]*\"[^>]*>(rfc[- ]?)([0-9]+)</a>","<a href=\"%s?%srfc=\g<7>#section-\g<2>\">\g<1> \g<2>\g<4>\g<6>\g<7></a>"% (script, extra), data)
data = re.sub("(?i)<a href=\"[^\"]*\"[^>]*>(section)\s(\d+(\.\d+)*)</a>(\s+(of|in)\s+)<a href=\"[^\"]*\"[^>]*>(bcp[- ]?)([0-9]+)</a>","<a href=\"%s?%sbcp=\g<7>#section-\g<2>\">\g<1> \g<2>\g<4>\g<6>\g<7></a>"% (script, extra), data)# rfc y, section x markup
data = re.sub("(?i)<a href=\"[^\"]*\"[^>]*>(rfc[- ]?)([0-9]+)</a>(,?\s+)<a href=\"[^\"]*\"[^>]*>(section)\s(\d+(\.\d+)*)</a>","<a href=\"%s?%srfc=\g<2>#section-\g<5>\">\g<1>\g<2>\g<3>\g<4> \g<5></a>"% (script, extra), data)
data = re.sub("(?i)<a href=\"[^\"]*\"[^>]*>(bcp[- ]?)([0-9]+)</a>(,?\s+)<a href=\"[^\"]*\"[^>]*>(section)\s(\d+(\.\d+)*)</a>","<a href=\"%s?%sbcp=\g<2>#section-\g<5>\">\g<1>\g<2>\g<3>\g<4> \g<5></a>"% (script, extra), data)# section x of? [rfc y] markup
data = re.sub("(?i)<a href=\"[^\"]*\"[^>]*>(section)\s(\d+(\.\d+)*)</a>(\s+(of\s+|in\s+)?)\[<a href=\"[^\"]*\"[^>]*>(rfc[- ]?)([0-9]+)</a>\]","<a href=\"%s?%srfc=\g<7>#section-\g<2>\">\g<1> \g<2>\g<4>[\g<6>\g<7>]</a>"% (script, extra), data)
data = re.sub("(?i)<a href=\"[^\"]*\"[^>]*>(section)\s(\d+(\.\d+)*)</a>(\s+(of\s+|in\s+)?)\[<a href=\"[^\"]*\"[^>]*>(bcp[- ]?)([0-9]+)</a>\]","<a href=\"%s?%sbcp=\g<7>#section-\g<2>\">\g<1> \g<2>\g<4>[\g<6>\g<7>]</a>"% (script, extra), data)# [rfc y], section x markup
data = re.sub("(?i)\[<a href=\"[^>\"]+\"[^>]*>(rfc[- ]?)([0-9]+)</a>\](,?\s+)<a href=\"[^>\"]*\"[^>]*>(section)\s(\d+(\.\d+)*)</a>","<a href=\"%s?%srfc=\g<2>#section-\g<5>\">[\g<1>\g<2>]\g<3>\g<4> \g<5></a>"% (script, extra), data)
data = re.sub("(?i)\[<a href=\"[^>\"]+\"[^>]*>(bcp[- ]?)([0-9]+)</a>\](,?\s+)<a href=\"[^>\"]*\"[^>]*>(section)\s(\d+(\.\d+)*)</a>","<a href=\"%s?%sbcp=\g<2>#section-\g<5>\">[\g<1>\g<2>]\g<3>\g<4> \g<5></a>"% (script, extra), data)# remove section link for section x.x (of|in) <something else>
old = data
data = re.sub("(?i)<a href=\"[^\"]*\"[^>]*>(section\s)(\d+(\.\d+)*)</a>(\s+(of|in)\s+)(\[?)<a href=\"([^\"]*)\"([^>]*)>(.*)</a>(\]?)",'\g<1>\g<2>\g<4>\g<6><a href="\g<7>"\g<8>>\g<9></a>\g<10>', data)
data = re.sub('(?i)(\[?)<a href="([^"]*)"([^>]*)>(.*?)</a>(\]?,\s+)<a href="[^"]*"[^>]*>(section\s)(\d+(\.\d+)*)</a>','\g<1><a href="\g<2>"\g<3>>\g<4></a>\g<5>\g<6>\g<7>', data)# # remove section link for <something>], section x.x# data = re.sub("(?i) \[<a href=\"([^\"]*)\"([^>]*)>(.*)</a>\] <a href=\"[^\"]*\"[^>]*>(section)\s(\d+(\.\d+)*)</a>",# "\g<1> \g<2>\g<4><a href=\"\g<6>\"\g<7>>[\g<8>]</a>", data)# appendix number tag markupdefappendix_replacement(match):# exclude TOC entries
mstring = match.group(0)if" \. \. "in mstring or"\.\.\."in mstring:return mstring
level =len(re.findall("[^\.]+", match.group(1)))+1if level >6:
level =6return"""<span class="h%s"><a name=\"appendix-%s\">%s%s</a>%s</span>"""% (level, match.group(2), match.group(1), match.group(2), match.group(4))
data = re.sub("(?m)^(Appendix |)([A-Z](\.\d+)*)(\.?[ ].*)$", appendix_replacement, data)#data = re.sub("(?i)(\n *\n *)(\d+(\.\d+)*)(\.?[ ].*)", appendix_replacement, data)# appendix number link markup
data = re.sub(" ([Aa]ppendix\s)([A-Z](\.\d+)*)"," <a href=\"#appendix-\g<2>\">\g<1>\g<2></a>", data)# comment markup
colorcount =0for tag in tags:
color = colors[colorcount%len(colors)]
colorcount +=1
data = re.sub("(?sm)^(%s.*?)(\n*)$"%tag,"<span style=\"color: %s\">\g<1></span>\g<2>"%color, data)##data = re.sub("\f", "<div class=\"newpage\" />", data)
data = re.sub("\f","</pre><pre class='newpage'>", data)# restore indentationif prefixlen:
data = re.sub("\n","\n"+(" "*prefixlen), data)if optstatic:
data = re.sub("%s\?(rfc|bcp|std)="% script,"./\g<1>", data)
data = re.sub("%s\?draft="% script,"./", data)# output modified dataprelude(optstatic)if optmenu:if draftname:
args["draftname"] = draftname
args["nitsmenu"] = nitsmenu % args
if os.path.exists("/www/tools.ietf.org/id/%s.html"%(draftname)):
args["htmllink"] = htmllink % args
if draftname and(draftname[-2:] !="00"or re.match(".*-(rfc)?[0-9][0-9][0-9]+bis-.*", draftname)or"docreplaces"in attribs):
args["diffmenu"] = diffmenu % args
if charter:
args["diffmenu"] = diffmenu % args
if rfc and"document"in attribs:if"docreplaces"in attribs:#args["doc"] = "%s/rfc%s.txt&url1=%s" % (rfcs, rfc, attribs["docreplaces"])pass
args["diffmenu"] = diffmenu % args
if wgname:
args["wgmenu"] = wgmenu % args
if draftname:
args["base"] = draftname[:-3]
args["emailmenu"] = emailmenu % args
if"docwg"in attribs and(attribs["docwg"] !='none'):
args["wg"] = attribs["docwg"]
args["wgmenu"] = wgmenu % args
if"docipr"in attribs:if draftname:
args["base"] = draftname[:-3]
args["iprmenu"] = draftiprmenu % args
else:
args["rfc"] = rfc
args["iprmenu"] = rfciprmenu % args
args["padding"] =" "*(72-len(re.sub("<.*?>","", (topmenu % args))))
sys.stdout.write(topmenu % args)if args["docinfo"]:
sys.stdout.write(docinfo % args)print data
postlude()if __name__ =="__main__":if"--version"in sys.argv:print"%(script)s\t%(version)s"% args
sys.exit()if"--help"in sys.argv:usage()
sys.exit()markup()