blob: dce947f72f7394a04bf663310f519abc1bed107f [file] [log] [blame]
Guido van Rossumea31ea21997-05-26 05:43:29 +00001"""FAQ Wizard customization module.
Guido van Rossum1677e5b1997-05-26 00:07:18 +00002
Guido van Rossumea31ea21997-05-26 05:43:29 +00003Edit this file to customize the FAQ Wizard. For normal purposes, you
4should only have to change the FAQ section titles and the small group
5of parameters below it.
Guido van Rossum1677e5b1997-05-26 00:07:18 +00006
Guido van Rossumea31ea21997-05-26 05:43:29 +00007"""
Guido van Rossum1677e5b1997-05-26 00:07:18 +00008
9# Titles of FAQ sections
Guido van Rossumea31ea21997-05-26 05:43:29 +000010
Guido van Rossum1677e5b1997-05-26 00:07:18 +000011SECTION_TITLES = {
Guido van Rossum23052311997-05-26 06:12:50 +000012 # SectionNumber : SectionTitle; need at least one entry
Guido van Rossum1677e5b1997-05-26 00:07:18 +000013 1: "General information and availability",
Guido van Rossum1677e5b1997-05-26 00:07:18 +000014}
15
Guido van Rossumea31ea21997-05-26 05:43:29 +000016# Parameters you definitely want to change
17
Guido van Rossum23052311997-05-26 06:12:50 +000018SHORTNAME = "Generic" # FAQ name with "FAQ" omitted
19PASSWORD = "" # Password for editing
Guido van Rossumea31ea21997-05-26 05:43:29 +000020OWNERNAME = "GvR" # Name for feedback
21OWNEREMAIL = "guido@python.org" # Email for feedback
22HOMEURL = "http://www.python.org" # Related home page
23HOMENAME = "Python home" # Name of related home page
Guido van Rossumea31ea21997-05-26 05:43:29 +000024RCSBINDIR = "/depot/gnu/plat/bin/" # Directory containing RCS commands
25 # (must end in a slash)
26
27# Parameters you can normally leave alone
28
Guido van Rossumea31ea21997-05-26 05:43:29 +000029MAXHITS = 10 # Max #hits to be shown directly
30COOKIE_LIFETIME = 28*24*3600 # Cookie expiration in seconds
31 # (28*24*3600 = 28 days = 4 weeks)
32
Guido van Rossumfd67f731997-05-26 19:46:18 +000033# Markers appended to title to indicate recently change
34# (may contain HTML, e.g. <IMG>); and corresponding
35
36MARK_VERY_RECENT = " **" # Changed very recently
37MARK_RECENT = " *" # Changed recently
38DT_VERY_RECENT = 24*3600 # 24 hours
39DT_RECENT = 7*24*3600 # 7 days
40
41EXPLAIN_MARKS = """
Guido van Rossumd812c071997-05-26 20:15:44 +000042<P>(Entries marked with ** were changed within the last 24 hours;
Guido van Rossumfd67f731997-05-26 19:46:18 +000043entries marked with * were changed within the last 7 days.)
44<P>
45"""
46
47# Version -- don't change unless you edit faqwiz.py
48
Guido van Rossum4f074041997-06-02 21:40:18 +000049WIZVERSION = "0.5" # FAQ Wizard version
Guido van Rossumfd67f731997-05-26 19:46:18 +000050
Guido van Rossum23052311997-05-26 06:12:50 +000051# This parameter is normally overwritten with a dynamic value
52
53FAQCGI = 'faqw.py' # Relative URL of the FAQ cgi script
54import os, sys
55FAQCGI = os.path.basename(sys.argv[0]) or FAQCGI
56del os, sys
57
Guido van Rossumfd67f731997-05-26 19:46:18 +000058# Regular expression to recognize FAQ entry files: group(1) should be
59# the section number, group(2) should be the question number. Both
60# should be fixed width so simple-minded sorting yields the right
61# order.
62
63OKFILENAME = "^faq\([0-9][0-9]\)\.\([0-9][0-9][0-9]\)\.htp$"
64
65# Format to construct a FAQ entry file name
66
67NEWFILENAME = "faq%02d.%03d.htp"
68
Guido van Rossum23052311997-05-26 06:12:50 +000069# Load local customizations on top of the previous parameters
70
71try:
72 from faqcust import *
Guido van Rossum178f58a1997-06-02 21:39:15 +000073except ImportError:
Guido van Rossum23052311997-05-26 06:12:50 +000074 pass
75
76# Calculated parameter names
77
78COOKIE_NAME = SHORTNAME + "-FAQ-Wizard" # Name used for Netscape cookie
79FAQNAME = SHORTNAME + " FAQ" # Name of the FAQ
80
Guido van Rossumfd67f731997-05-26 19:46:18 +000081# Load local customizations again, in case they set COOKIE_NAME or FAQNAME
Guido van Rossumea31ea21997-05-26 05:43:29 +000082
Guido van Rossumfd67f731997-05-26 19:46:18 +000083try:
84 from faqcust import *
Guido van Rossum178f58a1997-06-02 21:39:15 +000085except ImportError:
Guido van Rossumfd67f731997-05-26 19:46:18 +000086 pass
Guido van Rossumea31ea21997-05-26 05:43:29 +000087
88# ----------------------------------------------------------------------
89
90# Anything below this point normally needn't be changed; you would
91# change this if you were to create e.g. a French translation or if
92# you just aren't happy with the text generated by the FAQ Wizard.
93
94# Most strings here are subject to substitution (string%dictionary)
95
96# RCS commands
97
98SH_RLOG = RCSBINDIR + "rlog %(file)s </dev/null 2>&1"
99SH_RLOG_H = RCSBINDIR + "rlog -h %(file)s </dev/null 2>&1"
100SH_RDIFF = RCSBINDIR + "rcsdiff -r%(prev)s -r%(rev)s %(file)s </dev/null 2>&1"
Guido van Rossum8bc49c81997-05-26 19:10:37 +0000101SH_REVISION = RCSBINDIR + "co -p%(rev)s %(file)s </dev/null 2>&1"
Guido van Rossumea31ea21997-05-26 05:43:29 +0000102SH_LOCK = RCSBINDIR + "rcs -l %(file)s </dev/null 2>&1"
103SH_CHECKIN = RCSBINDIR + "ci -u %(file)s <%(tfn)s 2>&1"
104
105# Titles for various output pages (not subject to substitution)
106
107T_HOME = FAQNAME + " Wizard " + WIZVERSION
108T_ERROR = "Sorry, an error occurred"
109T_ROULETTE = FAQNAME + " Roulette"
110T_ALL = "The Whole " + FAQNAME
111T_INDEX = FAQNAME + " Index"
112T_SEARCH = FAQNAME + " Search Results"
113T_RECENT = "What's New in the " + FAQNAME
114T_SHOW = FAQNAME + " Entry"
115T_LOG = "RCS log for %s entry" % FAQNAME
Guido van Rossum8bc49c81997-05-26 19:10:37 +0000116T_REVISION = "RCS revision for %s entry" % FAQNAME
Guido van Rossumea31ea21997-05-26 05:43:29 +0000117T_DIFF = "RCS diff for %s entry" % FAQNAME
118T_ADD = "Add an entry to the " + FAQNAME
119T_DELETE = "Deleting an entry from the " + FAQNAME
120T_EDIT = FAQNAME + " Edit Wizard"
121T_REVIEW = T_EDIT + " - Review Changes"
122T_COMMITTED = T_EDIT + " - Changes Committed"
123T_COMMITFAILED = T_EDIT + " - Commit Failed"
124T_CANTCOMMIT = T_EDIT + " - Commit Rejected"
125T_HELP = T_EDIT + " - Help"
126
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000127# Generic prologue and epilogue
128
129PROLOGUE = '''
130<HTML>
131<HEAD>
132<TITLE>%(title)s</TITLE>
133</HEAD>
134
135<BODY BACKGROUND="http://www.python.org/pics/RedShort.gif"
136 BGCOLOR="#FFFFFF"
137 TEXT="#000000"
138 LINK="#AA0000"
139 VLINK="#906A6A">
140<H1>%(title)s</H1>
141'''
142
143EPILOGUE = '''
144<HR>
145<A HREF="%(HOMEURL)s">%(HOMENAME)s</A> /
Guido van Rossumea31ea21997-05-26 05:43:29 +0000146<A HREF="%(FAQCGI)s?req=home">%(FAQNAME)s Wizard %(WIZVERSION)s</A> /
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000147Feedback to <A HREF="mailto:%(OWNEREMAIL)s">%(OWNERNAME)s</A>
148
149</BODY>
150</HTML>
151'''
152
153# Home page
154
155HOME = """
Guido van Rossumea31ea21997-05-26 05:43:29 +0000156<H2>Search the %(FAQNAME)s:</H2>
157
158<BLOCKQUOTE>
159
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000160<FORM ACTION="%(FAQCGI)s">
161 <INPUT TYPE=text NAME=query>
162 <INPUT TYPE=submit VALUE="Search"><BR>
Guido van Rossumea31ea21997-05-26 05:43:29 +0000163 <INPUT TYPE=radio NAME=querytype VALUE=simple CHECKED>
164 Simple string
165 /
166 <INPUT TYPE=radio NAME=querytype VALUE=regex>
167 Regular expression
Guido van Rossum8bc49c81997-05-26 19:10:37 +0000168 /<BR>
Guido van Rossumd9936951997-05-26 16:35:27 +0000169 <INPUT TYPE=radio NAME=querytype VALUE=anykeywords>
170 Keywords (any)
171 /
172 <INPUT TYPE=radio NAME=querytype VALUE=allkeywords>
173 Keywords (all)
Guido van Rossumea31ea21997-05-26 05:43:29 +0000174 <BR>
175 <INPUT TYPE=radio NAME=casefold VALUE=yes CHECKED>
176 Fold case
177 /
178 <INPUT TYPE=radio NAME=casefold VALUE=no>
179 Case sensitive
180 <BR>
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000181 <INPUT TYPE=hidden NAME=req VALUE=search>
182</FORM>
183
Guido van Rossumea31ea21997-05-26 05:43:29 +0000184</BLOCKQUOTE>
185
186<HR>
187
188<H2>Other forms of %(FAQNAME)s access:</H2>
189
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000190<UL>
191<LI><A HREF="%(FAQCGI)s?req=index">FAQ index</A>
192<LI><A HREF="%(FAQCGI)s?req=all">The whole FAQ</A>
Guido van Rossumea31ea21997-05-26 05:43:29 +0000193<LI><A HREF="%(FAQCGI)s?req=recent">What's new in the FAQ?</A>
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000194<LI><A HREF="%(FAQCGI)s?req=roulette">FAQ roulette</A>
Guido van Rossumea31ea21997-05-26 05:43:29 +0000195<LI><A HREF="%(FAQCGI)s?req=add">Add a FAQ entry</A>
196<LI><A HREF="%(FAQCGI)s?req=delete">Delete a FAQ entry</A>
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000197</UL>
198"""
199
200# Index formatting
201
202INDEX_SECTION = """
203<P>
204<HR>
Guido van Rossumea31ea21997-05-26 05:43:29 +0000205<H2>%(sec)s. %(title)s</H2>
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000206<UL>
207"""
208
Guido van Rossumea31ea21997-05-26 05:43:29 +0000209INDEX_ADDSECTION = """
210<P>
211<LI><A HREF="%(FAQCGI)s?req=new&amp;section=%(sec)s">Add new entry</A>
212(at this point)
213"""
214
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000215INDEX_ENDSECTION = """
216</UL>
217"""
218
219INDEX_ENTRY = """\
Guido van Rossum030144d1997-05-26 16:02:56 +0000220<LI><A HREF="%(FAQCGI)s?req=show&amp;file=%(file)s">%(title)s</A>
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000221"""
222
Guido van Rossum8bc49c81997-05-26 19:10:37 +0000223LOCAL_ENTRY = """\
224<LI><A HREF="#%(sec)s.%(num)s">%(title)s</A>
225"""
226
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000227# Entry formatting
228
Guido van Rossumfd67f731997-05-26 19:46:18 +0000229ENTRY_HEADER1 = """
Guido van Rossumea31ea21997-05-26 05:43:29 +0000230<HR>
Guido van Rossumfd67f731997-05-26 19:46:18 +0000231<H2><A NAME="%(sec)s.%(num)s">%(title)s</A>\
232"""
233
234ENTRY_HEADER2 = """\
235</H2>
Guido van Rossumea31ea21997-05-26 05:43:29 +0000236"""
237
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000238ENTRY_FOOTER = """
Guido van Rossumea31ea21997-05-26 05:43:29 +0000239<A HREF="%(FAQCGI)s?req=edit&amp;file=%(file)s">Edit this entry</A> /
240<A HREF="%(FAQCGI)s?req=log&amp;file=%(file)s">Log info</A>
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000241"""
242
243ENTRY_LOGINFO = """
244/ Last changed on %(last_changed_date)s by
245<A HREF="mailto:%(last_changed_email)s">%(last_changed_author)s</A>
246"""
247
248# Search
249
250NO_HITS = """
251No hits.
252"""
253
254ONE_HIT = """
255Your search matched the following entry:
256"""
257
258FEW_HITS = """
Guido van Rossumea31ea21997-05-26 05:43:29 +0000259Your search matched the following %(count)s entries:
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000260"""
261
262MANY_HITS = """
Guido van Rossumea31ea21997-05-26 05:43:29 +0000263Your search matched more than %(MAXHITS)s entries.
264The %(count)s matching entries are presented here ordered by section:
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000265"""
266
267# RCS log and diff
268
269LOG = """
270Click on a revision line to see the diff between that revision and the
271previous one.
272"""
273
Guido van Rossum8bc49c81997-05-26 19:10:37 +0000274REVISIONLINK = """\
275<A HREF="%(FAQCGI)s?req=revision&amp;file=%(file)s&amp;rev=%(rev)s"
276>%(line)s</A>\
277"""
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000278DIFFLINK = """\
Guido van Rossum8bc49c81997-05-26 19:10:37 +0000279 (<A HREF="%(FAQCGI)s?req=diff&amp;file=%(file)s&amp;\
280prev=%(prev)s&amp;rev=%(rev)s"
281>diff -r%(prev)s -r%(rev)s</A>)\
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000282"""
283
284# Recently changed entries
285
286NO_RECENT = """
287<HR>
288No %(FAQNAME)s entries were changed in the last %(period)s.
289"""
290
Guido van Rossumea31ea21997-05-26 05:43:29 +0000291VIEW_MENU = """
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000292<HR>
Guido van Rossumea31ea21997-05-26 05:43:29 +0000293View entries changed in the last...
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000294<UL>
Guido van Rossumea31ea21997-05-26 05:43:29 +0000295<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=1">24 hours</A>
296<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=2">2 days</A>
297<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=3">3 days</A>
298<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=7">week</A>
299<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=28">4 weeks</A>
300<LI><A HREF="%(FAQCGI)s?req=recent&amp;days=365250">millennium</A>
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000301</UL>
Guido van Rossumea31ea21997-05-26 05:43:29 +0000302"""
303
304ONE_RECENT = VIEW_MENU + """
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000305The following %(FAQNAME)s entry was changed in the last %(period)s:
306"""
307
Guido van Rossumea31ea21997-05-26 05:43:29 +0000308SOME_RECENT = VIEW_MENU + """
309The following %(count)s %(FAQNAME)s entries were changed
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000310in the last %(period)s, most recently changed shown first:
311"""
312
Guido van Rossumea31ea21997-05-26 05:43:29 +0000313TAIL_RECENT = VIEW_MENU
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000314
315# Last changed banner on "all" (strftime format)
316LAST_CHANGED = "Last changed on %c %Z"
317
Guido van Rossumea31ea21997-05-26 05:43:29 +0000318# "Compat" command prologue (this has no <BODY> tag)
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000319COMPAT = """
320<H1>The whole %(FAQNAME)s</H1>
321"""
322
323# Editing
324
325EDITHEAD = """
326<A HREF="%(FAQCGI)s?req=help">Click for Help</A>
327"""
328
329REVIEWHEAD = EDITHEAD
330
331
332EDITFORM1 = """
333<FORM ACTION="%(FAQCGI)s" METHOD=POST>
334<INPUT TYPE=hidden NAME=req VALUE=review>
335<INPUT TYPE=hidden NAME=file VALUE=%(file)s>
336<INPUT TYPE=hidden NAME=editversion VALUE=%(editversion)s>
337<HR>
338"""
339
340EDITFORM2 = """
341Title: <INPUT TYPE=text SIZE=70 NAME=title VALUE="%(title)s"><BR>
342<TEXTAREA COLS=72 ROWS=20 NAME=body>%(body)s
343</TEXTAREA><BR>
344Log message (reason for the change):<BR>
345<TEXTAREA COLS=72 ROWS=5 NAME=log>%(log)s
346</TEXTAREA><BR>
347Please provide the following information for logging purposes:
348<TABLE FRAME=none COLS=2>
349 <TR>
350 <TD>Name:
351 <TD><INPUT TYPE=text SIZE=40 NAME=author VALUE="%(author)s">
352 <TR>
353 <TD>Email:
354 <TD><INPUT TYPE=text SIZE=40 NAME=email VALUE="%(email)s">
355 <TR>
356 <TD>Password:
357 <TD><INPUT TYPE=password SIZE=20 NAME=password VALUE="%(password)s">
358</TABLE>
359
360<INPUT TYPE=submit NAME=review VALUE="Preview Edit">
361Click this button to preview your changes.
362"""
363
364EDITFORM3 = """
365</FORM>
366"""
367
368COMMIT = """
369<INPUT TYPE=submit NAME=commit VALUE="Commit">
370Click this button to commit your changes.
371<HR>
372"""
373
374NOCOMMIT = """
Guido van Rossumea31ea21997-05-26 05:43:29 +0000375To commit your changes, please enter a log message, your name, email
376addres, and the correct password in the form below.
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000377<HR>
378"""
379
380CANTCOMMIT_HEAD = """
381Some required information is missing:
382<UL>
383"""
384NEED_PASSWD = "<LI>You must provide the correct passwd.\n"
385NEED_AUTHOR = "<LI>You must enter your name.\n"
386NEED_EMAIL = "<LI>You must enter your email address.\n"
387NEED_LOG = "<LI>You must enter a log message.\n"
388CANTCOMMIT_TAIL = """
389</UL>
390Please use your browser's Back command to correct the form and commit
391again.
392"""
393
Guido van Rossumea31ea21997-05-26 05:43:29 +0000394NEWCONFLICT = """
395<P>
396You are creating a new entry, but the entry number specified is not
397correct.
398<P>
399The two most common causes of this problem are:
400<UL>
401<LI>After creating the entry yourself, you went back in your browser,
402 edited the entry some more, and clicked Commit again.
403<LI>Someone else started creating a new entry in the same section and
404 committed before you did.
405</UL>
406(It is also possible that the last entry in the section was physically
407deleted, but this should not happen except through manual intervention
408by the FAQ maintainer.)
409<P>
410<A HREF="%(FAQCGI)s?req=new&amp;section=%(sec)s">Click here to try
411again.</A>
412<P>
413"""
414
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000415VERSIONCONFLICT = """
416<P>
417You edited version %(editversion)s but the current version is %(version)s.
418<P>
419The two most common causes of this problem are:
420<UL>
421<LI>After committing a change, you went back in your browser,
422 edited the entry some more, and clicked Commit again.
423<LI>Someone else started editing the same entry and committed
424 before you did.
425</UL>
426<P>
Guido van Rossumea31ea21997-05-26 05:43:29 +0000427<A HREF="%(FAQCGI)s?req=show&amp;file=%(file)s">Click here to reload
428the entry and try again.</A>
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000429<P>
430"""
431
432CANTWRITE = """
433Can't write file %(file)s (%(why)s).
434"""
435
436FILEHEADER = """\
437Title: %(title)s
438Last-Changed-Date: %(date)s
439Last-Changed-Author: %(author)s
440Last-Changed-Email: %(email)s
441Last-Changed-Remote-Host: %(REMOTE_HOST)s
442Last-Changed-Remote-Address: %(REMOTE_ADDR)s
443"""
444
445LOGHEADER = """\
446Last-Changed-Date: %(date)s
447Last-Changed-Author: %(author)s
448Last-Changed-Email: %(email)s
449Last-Changed-Remote-Host: %(REMOTE_HOST)s
450Last-Changed-Remote-Address: %(REMOTE_ADDR)s
451
452%(log)s
453"""
454
455COMMITTED = """
456Your changes have been committed.
457"""
458
459COMMITFAILED = """
460Exit status %(sts)04x.
461"""
462
Guido van Rossumea31ea21997-05-26 05:43:29 +0000463# Add/Delete
464
465ADD_HEAD = """
466At the moment, new entries can only be added at the end of a section.
467This is because the entry numbers are also their
468unique identifiers -- it's a bad idea to renumber entries.
469<P>
470Click on the section to which you want to add a new entry:
471<UL>
472"""
473
474ADD_SECTION = """\
475<LI><A HREF="%(FAQCGI)s?req=new&amp;section=%(section)s">%(section)s. %(title)s</A>
476"""
477
478ADD_TAIL = """
479</UL>
480"""
481
482DELETE = """
483At the moment, there's no direct way to delete entries.
484This is because the entry numbers are also their
485unique identifiers -- it's a bad idea to renumber entries.
486<P>
487If you really think an entry needs to be deleted,
488change the title to "(deleted)" and make the body
489empty (keep the entry number in the title though).
490"""
491
492# Help file for the FAQ Edit Wizard
493
Guido van Rossum1677e5b1997-05-26 00:07:18 +0000494HELP = """
495Using the %(FAQNAME)s Edit Wizard speaks mostly for itself. Here are
496some answers to questions you are likely to ask:
497
498<P><HR>
499
500<H2>I can review an entry but I can't commit it.</H2>
501
502The commit button only appears if the following conditions are met:
503
504<UL>
505
506<LI>The Name field is not empty.
507
508<LI>The Email field contains at least an @ character.
509
510<LI>The Log message box is not empty.
511
512<LI>The Password field contains the proper password.
513
514</UL>
515
516<P><HR>
517
518<H2>What is the password?</H2>
519
520At the moment, only PSA members will be told the password. This is a
521good time to join the PSA! See <A
522HREF="http://www.python.org/psa/">the PSA home page</A>.
523
524<P><HR>
525
526<H2>Can I use HTML in the FAQ entry?</H2>
527
528No, but if you include a URL or an email address in the text it will
529automatigally become an anchor of the right type. Also, *word*
530is made italic (but only for single alphabetic words).
531
532<P><HR>
533
534<H2>How do I delineate paragraphs?</H2>
535
536Use blank lines to separate paragraphs.
537
538<P><HR>
539
540<H2>How do I enter example text?</H2>
541
542Any line that begins with a space or tab is assumed to be part of
543literal text. Blocks of literal text delineated by blank lines are
544placed inside &lt;PRE&gt;...&lt;/PRE&gt;.
545"""