summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Rackham <srackham@methods.co.nz>2010-09-28 16:08:57 +1300
committerStuart Rackham <srackham@methods.co.nz>2010-09-28 16:08:57 +1300
commitc2f943bcaabf71e53535ef2a2101a2cf5cb0f347 (patch)
tree43d5fac58f2c686a2064d5cf7b7a00e9ca0212be
parent065b605f6b0d04877215099633ff30a372fc8527 (diff)
downloadasciidoc-c2f943bcaabf71e53535ef2a2101a2cf5cb0f347.tar.gz
Backend specific global configuration files (excluding `asciidoc.conf`) are
loaded *after* the header has been parsed.
-rwxr-xr-xasciidoc.py357
-rw-r--r--doc/asciidoc.txt111
-rw-r--r--docbook45.conf3
-rw-r--r--filters/graphviz/graphviz-filter.conf4
-rw-r--r--filters/source/source-highlight-filter.conf14
-rw-r--r--html4.conf1
-rw-r--r--lang-de.conf2
-rw-r--r--lang-en.conf2
-rw-r--r--lang-es.conf2
-rw-r--r--lang-fr.conf2
-rw-r--r--lang-hu.conf2
-rw-r--r--lang-it.conf2
-rw-r--r--lang-pt-BR.conf2
-rw-r--r--lang-ru.conf2
-rw-r--r--tests/data/lang-de-test.txt6
-rw-r--r--tests/data/lang-en-test.txt6
-rw-r--r--tests/data/lang-es-test.txt6
-rw-r--r--tests/data/lang-fr-test.txt6
-rw-r--r--tests/data/lang-hu-test.txt6
-rw-r--r--tests/data/lang-pt-BR-test.txt6
-rw-r--r--tests/data/lang-ru-test.txt6
-rw-r--r--tests/data/testcases.txt4
-rw-r--r--tests/testasciidoc.conf4
-rw-r--r--xhtml11.conf19
24 files changed, 329 insertions, 246 deletions
diff --git a/asciidoc.py b/asciidoc.py
index ec8f410..ad241b8 100755
--- a/asciidoc.py
+++ b/asciidoc.py
@@ -9,7 +9,7 @@ under the terms of the GNU General Public License (GPL).
import sys, os, re, time, traceback, tempfile, subprocess, codecs, locale
### Used by asciidocapi.py ###
-VERSION = '8.6.1' # See CHANGLOG file for version history.
+VERSION = '8.7.0b1' # See CHANGLOG file for version history.
MIN_PYTHON_VERSION = 2.4 # Require this version of Python or better.
@@ -168,7 +168,9 @@ class Message:
PROG = os.path.basename(os.path.splitext(__file__)[0])
def __init__(self):
- self.linenos = None # Used to globally override line numbers.
+ # Set to True or False to globally override line numbers method
+ # argument. Has no effect when set to None.
+ self.linenos = None
self.messages = []
def stderr(self,msg=''):
@@ -1271,10 +1273,27 @@ class Lex:
# Document element classes parse AsciiDoc reader input and write DocBook writer
# output.
#---------------------------------------------------------------------------
-class Document:
+class Document(object):
+
+ # doctype property.
+ def getdoctype(self):
+ return self.attributes.get('doctype')
+ def setdoctype(self,doctype):
+ self.attributes['doctype'] = doctype
+ doctype = property(getdoctype,setdoctype)
+
+ # backend property.
+ def getbackend(self):
+ return self.attributes.get('backend')
+ def setbackend(self,backend):
+ if backend:
+ backend = self.attributes.get('backend-alias-' + backend, backend)
+ self.attributes['backend'] = backend
+ backend = property(getbackend,setbackend)
+
def __init__(self):
- self.doctype = None # 'article','manpage' or 'book'.
- self.backend = None # -b option argument.
+# self.doctype = None # 'article','manpage' or 'book'.
+# self.backend = None # -b option argument.
self.infile = None # Source file name.
self.outfile = None # Output file name.
self.attributes = InsensitiveDict()
@@ -1284,34 +1303,13 @@ class Document:
self.safe = False # Default safe mode.
def update_attributes(self):
# Set implicit attributes.
- if self.infile and os.path.exists(self.infile):
- t = os.path.getmtime(self.infile)
- elif self.infile == '<stdin>':
- t = time.time()
- else:
- t = None
- if t:
- self.attributes['doctime'] = time_str(t)
- self.attributes['docdate'] = date_str(t)
t = time.time()
self.attributes['localtime'] = time_str(t)
self.attributes['localdate'] = date_str(t)
self.attributes['asciidoc-version'] = VERSION
- self.attributes['backend'] = document.backend
- self.attributes['doctype'] = document.doctype
- self.attributes['backend-'+document.backend] = ''
- self.attributes['doctype-'+document.doctype] = ''
- self.attributes[document.backend+'-'+document.doctype] = ''
self.attributes['asciidoc-file'] = APP_FILE
self.attributes['asciidoc-dir'] = APP_DIR
self.attributes['user-dir'] = USER_DIR
- if self.infile != '<stdin>':
- self.attributes['infile'] = self.infile
- self.attributes['indir'] = os.path.dirname(self.infile)
- self.attributes['docfile'] = self.infile
- self.attributes['docdir'] = os.path.dirname(self.infile)
- self.attributes['docname'] = os.path.splitext(
- os.path.basename(self.infile))[0]
if config.verbose:
self.attributes['verbose'] = ''
# Update with configuration file attributes.
@@ -1322,6 +1320,24 @@ class Document:
config.load_miscellaneous(config.conf_attrs)
config.load_miscellaneous(config.cmd_attrs)
self.attributes['newline'] = config.newline
+ # File name related attributes can't be overridden.
+ if self.infile is not None:
+ if self.infile and os.path.exists(self.infile):
+ t = os.path.getmtime(self.infile)
+ elif self.infile == '<stdin>':
+ t = time.time()
+ else:
+ t = None
+ if t:
+ self.attributes['doctime'] = time_str(t)
+ self.attributes['docdate'] = date_str(t)
+ if self.infile != '<stdin>':
+ self.attributes['infile'] = self.infile
+ self.attributes['indir'] = os.path.dirname(self.infile)
+ self.attributes['docfile'] = self.infile
+ self.attributes['docdir'] = os.path.dirname(self.infile)
+ self.attributes['docname'] = os.path.splitext(
+ os.path.basename(self.infile))[0]
if self.outfile:
if self.outfile != '<stdout>':
self.attributes['outfile'] = self.outfile
@@ -1336,7 +1352,7 @@ class Document:
if ext:
self.attributes['filetype'] = ext
self.attributes['filetype-'+ext] = ''
- def load_lang(self,linenos=False):
+ def load_lang(self):
"""
Load language configuration file.
"""
@@ -1345,7 +1361,6 @@ class Document:
filename = 'lang-en.conf' # Default language file.
else:
filename = 'lang-' + lang + '.conf'
- message.linenos = linenos
if config.load_from_dirs(filename):
self.attributes['lang'] = lang # Reinstate new lang attribute.
else:
@@ -1354,7 +1369,6 @@ class Document:
message.error('missing conf file: %s' % filename, halt=True)
else:
message.warning('missing language conf file: %s' % filename)
- message.linenos = None # Restore default line number behavior.
def set_deprecated_attribute(self,old,new):
"""
Ensures the 'old' name of an attribute that was renamed to 'new' is
@@ -1365,60 +1379,110 @@ class Document:
self.attributes[new] = self.attributes[old]
else:
self.attributes[old] = self.attributes[new]
- def consume_attributes_and_comments(self,comments_only=False):
+ def consume_attributes_and_comments(self,comments_only=False,noblanks=False):
+ """
+ Returns True if one or more attributes or comments were consumed.
+ If 'noblanks' is True then consumation halts if a blank line is
+ encountered.
+ """
+ result = False
finished = False
while not finished:
finished = True
+ if noblanks and not reader.read_next(): return result
if blocks.isnext() and 'skip' in blocks.current.options:
+ result = True
finished = False
blocks.current.translate()
+ if noblanks and not reader.read_next(): return result
if macros.isnext() and macros.current.name == 'comment':
+ result = True
finished = False
macros.current.translate()
if not comments_only:
if AttributeEntry.isnext():
+ result = True
finished = False
AttributeEntry.translate()
- if AttributeEntry.name == 'lang':
- message.error('lang attribute must be first entry')
if AttributeList.isnext():
+ result = True
finished = False
AttributeList.translate()
+ return result
def consume_comments(self):
self.consume_attributes_and_comments(comments_only=True)
- def translate(self):
- assert self.doctype in ('article','manpage','book'), \
- 'illegal document type'
+ def parse_header(self,doctype,backend):
+ """
+ Parses header, sets corresponding document attributes and finalizes
+ document doctype and backend properties.
+ Returns False if the document does not have a header.
+ 'doctype' and 'backend' are the doctype and backend option values
+ passed on the command-line, None if no command-line option was not
+ specified.
+ """
assert self.level == 0
- message.verbose('writing: '+writer.fname,False)
- # Skip leading comments.
- self.consume_comments()
- # Load language configuration file.
- loaded = False
- if AttributeEntry.isnext() and AttributeEntry.name == 'lang':
- # The first non-comment in the document can be 'lang' attribute.
- AttributeEntry.translate()
- if 'lang' not in config.cmd_attrs:
- self.load_lang(linenos=True)
- loaded = True
- if not loaded:
- self.load_lang()
- # All configuration files have been loaded so can expand templates.
- config.expand_all_templates()
# Skip comments and attribute entries that preceed the header.
self.consume_attributes_and_comments()
+ if doctype is not None:
+ # Command-line overrides header.
+ self.doctype = doctype
+ elif self.doctype is None:
+ # Was not set on command-line or in document header.
+ self.doctype = DEFAULT_DOCTYPE
# Process document header.
- has_header = Lex.next() is Title and Title.level == 0
+ has_header = (Title.isnext() and Title.level == 0
+ and AttributeList.style() != 'float')
if self.doctype == 'manpage' and not has_header:
- message.error('manpage document title is mandatory')
+ message.error('manpage document title is mandatory',halt=True)
+ tmp = self.doctype
+ if has_header:
+ Header.parse()
+ if self.doctype != tmp and self.doctype == 'manpage':
+ message.error('doctype manpage must be set before the title',halt=True)
+ # Command-line entries override header derived entries.
+ self.attributes.update(config.cmd_attrs)
+ # DEPRECATED: revision renamed to revnumber.
+ self.set_deprecated_attribute('revision','revnumber')
+ # DEPRECATED: date renamed to revdate.
+ self.set_deprecated_attribute('date','revdate')
+ if doctype is not None:
+ # Command-line overrides header.
+ self.doctype = doctype
+ if backend is not None:
+ # Command-line overrides header.
+ self.backend = backend
+ elif self.backend is None:
+ # Was not set on command-line or in document header.
+ self.backend = DEFAULT_BACKEND
+ else:
+ # Has been set in document header.
+ self.backend = self.backend # Translate alias in header.
+ assert self.doctype in ('article','manpage','book'), 'illegal document type'
+ return has_header
+ def translate(self,has_header):
+ if self.doctype == 'manpage':
+ # Translate mandatory NAME section.
+ if Lex.next() is not Title:
+ message.error('name section expected')
+ else:
+ Title.translate()
+ if Title.level != 1:
+ message.error('name section title must be at level 1')
+ if not isinstance(Lex.next(),Paragraph):
+ message.error('malformed name section body')
+ lines = reader.read_until(r'^$')
+ s = ' '.join(lines)
+ mo = re.match(r'^(?P<manname>.*?)\s+-\s+(?P<manpurpose>.*)$',s)
+ if not mo:
+ message.error('malformed name section body')
+ self.attributes['manname'] = mo.group('manname').strip()
+ self.attributes['manpurpose'] = mo.group('manpurpose').strip()
+ names = [s.strip() for s in self.attributes['manname'].split(',')]
+ if len(names) > 9:
+ message.warning('to many manpage names')
+ for i,name in enumerate(names):
+ self.attributes['manname%d' % (i+1)] = name
if has_header:
- Header.translate()
- # Command-line entries override header derived entries.
- self.attributes.update(config.cmd_attrs)
- # DEPRECATED: revision renamed to revnumber.
- self.set_deprecated_attribute('revision','revnumber')
- # DEPRECATED: date renamed to revdate.
- self.set_deprecated_attribute('date','revdate')
if config.header_footer:
hdr = config.subs_section('header',{})
writer.write(hdr,trace='header')
@@ -1432,7 +1496,7 @@ class Document:
Section.translate_body()
writer.write(etag,trace='preamble close')
else:
- document.process_author_names()
+ self.process_author_names()
if config.header_footer:
hdr = config.subs_section('header',{})
writer.write(hdr,trace='header')
@@ -1530,7 +1594,7 @@ class Header:
def __init__(self):
raise AssertionError,'no class instances allowed'
@staticmethod
- def translate():
+ def parse():
assert Lex.next() is Title and Title.level == 0
Title.translate()
attrs = document.attributes # Alias for readability.
@@ -1548,24 +1612,27 @@ class Header:
mantitle = mantitle.lower()
attrs['mantitle'] = mantitle;
attrs['manvolnum'] = mo.group('manvolnum').strip()
- AttributeEntry.translate_all()
+ document.consume_attributes_and_comments(noblanks=True)
s = reader.read_next()
mo = None
if s:
+ # Process first header line after the title that is not a comment
+ # or an attribute entry.
s = reader.read()
mo = re.match(Header.RCS_ID_RE,s)
if not mo:
document.parse_author(s)
- AttributeEntry.translate_all()
+ document.consume_attributes_and_comments(noblanks=True)
if reader.read_next():
- # Parse revision line.
+ # Process second header line after the title that is not a
+ # comment or an attribute entry.
s = reader.read()
s = subs_attrs(s)
if s:
mo = re.match(Header.RCS_ID_RE,s)
if not mo:
mo = re.match(Header.REV_LINE_RE,s)
- AttributeEntry.translate_all()
+ document.consume_attributes_and_comments(noblanks=True)
s = attrs.get('revnumber')
if s:
mo = re.match(Header.RCS_ID_RE,s)
@@ -1580,40 +1647,19 @@ class Header:
if revremark is not None:
revremark = [revremark]
# Revision remarks can continue on following lines.
- while reader.read_next() and not AttributeEntry.isnext():
+ while reader.read_next():
+ if document.consume_attributes_and_comments(noblanks=True):
+ break
revremark.append(reader.read())
revremark = Lex.subs(revremark,['normal'])
revremark = '\n'.join(revremark).strip()
attrs['revremark'] = revremark
- AttributeEntry.translate_all()
revdate = mo.group('revdate')
if revdate:
attrs['revdate'] = revdate.strip()
elif revnumber or revremark:
# Set revision date to ensure valid DocBook revision.
attrs['revdate'] = attrs['docdate']
- if document.doctype == 'manpage':
- # Translate mandatory NAME section.
- if Lex.next() is not Title:
- message.error('name section expected')
- else:
- Title.translate()
- if Title.level != 1:
- message.error('name section title must be at level 1')
- if not isinstance(Lex.next(),Paragraph):
- message.error('malformed name section body')
- lines = reader.read_until(r'^$')
- s = ' '.join(lines)
- mo = re.match(r'^(?P<manname>.*?)\s+-\s+(?P<manpurpose>.*)$',s)
- if not mo:
- message.error('malformed name section body')
- attrs['manname'] = mo.group('manname').strip()
- attrs['manpurpose'] = mo.group('manpurpose').strip()
- names = [s.strip() for s in attrs['manname'].split(',')]
- if len(names) > 9:
- message.warning('to many manpage names')
- for i,name in enumerate(names):
- attrs['manname%d' % (i+1)] = name
document.process_author_names()
class AttributeEntry:
@@ -1690,11 +1736,6 @@ class AttributeEntry:
document.attributes[attr.name] = attr.value
elif attr.name in document.attributes:
del document.attributes[attr.name]
- @staticmethod
- def translate_all():
- """ Process all contiguous attribute lines on reader."""
- while AttributeEntry.isnext():
- AttributeEntry.translate()
class AttributeList:
"""Static methods and attributes only."""
@@ -4102,6 +4143,7 @@ class Writer:
self.f = sys.stdout
else:
self.f = open(fname,'wb+')
+ message.verbose('writing: '+writer.fname,False)
if bom:
self.f.write(bom)
self.lines_out = 0
@@ -4229,7 +4271,9 @@ class Config:
if os.path.realpath(fname) in self.loaded:
return True
rdr = Reader() # Reader processes system macros.
+ message.linenos = False # Disable document line numbers.
rdr.open(fname)
+ message.linenos = None
self.fname = fname
reo = re.compile(r'(?u)^\[(?P<section>[^\W\d][\w-]*)\]\s*$')
sections = OrderedDict()
@@ -4270,8 +4314,7 @@ class Config:
rdr.close()
self.load_sections(sections)
self.loaded.append(os.path.realpath(fname))
- if document.infile is not None:
- document.update_attributes() # So they are available immediately.
+ document.update_attributes() # So they are available immediately.
return True
def load_sections(self,sections):
@@ -4314,7 +4357,9 @@ class Config:
macros.load(sections.get('macros',()))
def get_load_dirs(self):
- """Return list of well known paths to search for conf files."""
+ """
+ Return list of well known paths with conf files.
+ """
result = []
if localapp():
# Load from folders in asciidoc executable directory.
@@ -4325,9 +4370,6 @@ class Config:
# Load configuration files from ~/.asciidoc if it exists.
if USER_DIR is not None:
result.append(USER_DIR)
- # Load configuration files from document directory.
- if document.infile not in (None,'<stdin>'):
- result.append(os.path.dirname(document.infile))
return result
def find_in_dirs(self, filename, dirs=None):
@@ -4357,29 +4399,27 @@ class Config:
count += 1
return count != 0
- def load_all(self, dirs=None):
+ def load_backend(self, dirs=None):
"""
- Load the standard configuration (except the language file)
- files from dirs list.
+ Load the backend configuration files from dirs list.
If dirs not specified try all the well known locations.
"""
if dirs is None:
dirs = self.get_load_dirs()
for d in dirs:
- # asciidoc.conf's take precedence over other conf files.
- self.load_file('asciidoc.conf',d)
- alias = 'backend-alias-' + document.backend
- if alias in document.attributes:
- document.backend = document.attributes[alias]
- document.update_attributes() # Update backend related attributes.
- f = document.backend + '.conf'
- if not self.find_in_dirs(f):
- message.warning('missing backend conf file: %s' % f, linenos=False)
- for d in dirs:
conf = document.backend + '.conf'
self.load_file(conf,d)
conf = document.backend + '-' + document.doctype + '.conf'
self.load_file(conf,d)
+
+ def load_filters(self, dirs=None):
+ """
+ Load filter configuration files from 'filters' directory in dirs list.
+ If dirs not specified try all the well known locations.
+ """
+ if dirs is None:
+ dirs = self.get_load_dirs()
+ for d in dirs:
# Load filter .conf files.
filtersdir = os.path.join(d,'filters')
for dirpath,dirnames,filenames in os.walk(filtersdir):
@@ -4546,14 +4586,6 @@ class Config:
[tags] section. Raise error if not found. If a dictionary 'd' is
passed then merge with document attributes and perform attribute
substitution on tags."""
-
- # TODO: Tags should be stored a single string, not split into start
- # and end tags since most are going to be substituted anyway (see
- # subs_tag() for how we should process them. parse_tags() (above)
- # should only validate i.e. parse_check(). This routine should be renamed
- # split_tag() and would call subs_tag(). self.tags dictionary values
- # would be strings not tuples.
-
if not name in self.tags:
raise EAsciiDoc, 'missing tag: %s' % name
stag,etag = self.tags[name]
@@ -4735,7 +4767,6 @@ class Config:
# Deprecated old table classes follow.
# Naming convention is an _OLD name suffix.
# These will be removed from future versions of AsciiDoc
-#
def join_lines_OLD(lines):
"""Return a list in which lines terminated with the backslash line
@@ -5266,12 +5297,8 @@ def asciidoc(backend, doctype, confiles, infile, outfile, options):
The AsciiDoc document is read from file object src the translated
DocBook file written to file object dst."""
try:
- if doctype not in ('article','manpage','book'):
+ if doctype not in (None,'article','manpage','book'):
raise EAsciiDoc,'illegal document type'
- document.backend = backend
- document.doctype = doctype
- document.infile = infile
- document.update_attributes()
# Set processing options.
for o in options:
if o == '-c': config.dumping = True
@@ -5280,47 +5307,73 @@ def asciidoc(backend, doctype, confiles, infile, outfile, options):
# Check the infile exists.
if infile != '<stdin>' and not os.path.isfile(infile):
raise EAsciiDoc,'input file %s missing' % infile
+ document.infile = infile
+ # Load asciidoc.conf files.
+ if not config.load_from_dirs('asciidoc.conf'):
+ raise EAsciiDoc,'configuration file asciidoc.conf missing'
+ AttributeList.initialize()
+ # Open input file and parse document header.
+ reader.tabsize = config.tabsize
+ reader.open(infile)
+ has_header = document.parse_header(doctype,backend)
+ # doctype is now finalized.
+ document.attributes['doctype-'+document.doctype] = ''
+ # Load backend configuration files.
+ if '-e' not in options:
+ f = document.backend + '.conf'
+ if not config.find_in_dirs(f):
+ message.warning('missing backend conf file: %s' % f, linenos=False)
+ config.load_backend()
+ # backend is now finalized.
+ document.attributes['backend-'+document.backend] = ''
+ document.attributes[document.backend+'-'+document.doctype] = ''
+ # Load filters and language file.
if '-e' not in options:
- config.load_all()
+ config.load_filters()
+ document.load_lang()
+ # Load local conf files (conf files in the input file directory).
if infile != '<stdin>':
- # Load implicit document specific configuration files if they exist.
- config.load_file(os.path.splitext(infile)[0] + '.conf')
- config.load_file(os.path.splitext(infile)[0] + '-' + backend + '.conf')
- # If user specified configuration file(s) overlay the defaults.
+ d =os.path.dirname(infile)
+ config.load_from_dirs('asciidoc.conf', [d])
+ config.load_backend([d])
+ config.load_filters([d])
+ # Load document specific configuration files.
+ f = os.path.splitext(infile)[0]
+ config.load_file(f + '.conf')
+ config.load_file(f + '-' + document.backend + '.conf')
+ # Load conf files specified on the command-line.
if confiles:
for conf in confiles:
if os.path.isfile(conf):
config.load_file(conf)
else:
raise EAsciiDoc,'configuration file %s missing' % conf
- document.update_attributes()
- # Check configuration for consistency.
- config.validate()
- # Build outfile name now all conf files have been read.
+ # Build outfile name.
if outfile is None:
- outfile = os.path.splitext(infile)[0] + '.' + backend
+ outfile = os.path.splitext(infile)[0] + '.' + document.backend
if config.outfilesuffix:
# Change file extension.
outfile = os.path.splitext(outfile)[0] + config.outfilesuffix
document.outfile = outfile
+ document.update_attributes()
+ # Check configuration for consistency.
+ config.validate()
+ paragraphs.initialize()
+ lists.initialize()
if config.dumping:
config.dump()
else:
- reader.tabsize = config.tabsize
- reader.open(infile)
+ # Configuration is fully loaded so can expand templates.
+ config.expand_all_templates()
+ writer.newline = config.newline
try:
- writer.newline = config.newline
writer.open(outfile, reader.bom)
try:
- AttributeList.initialize()
- paragraphs.initialize()
- lists.initialize()
- document.update_attributes() # Add file name related.
- document.translate()
+ document.translate(has_header) # Generate the output.
finally:
writer.close()
finally:
- reader.closefile() # Keep reader state for postmortem.
+ reader.closefile()
except KeyboardInterrupt:
raise
except Exception,e:
@@ -5429,8 +5482,8 @@ def execute(cmd,opts,args):
if len(args) > 1:
usage('To many arguments')
sys.exit(1)
- backend = DEFAULT_BACKEND
- doctype = DEFAULT_DOCTYPE
+ backend = None
+ doctype = None
confiles = []
outfile = None
options = []
@@ -5448,10 +5501,12 @@ def execute(cmd,opts,args):
sys.exit(0)
if o in ('-b','--backend'):
backend = v
+# config.cmd_attrs['backend'] = v
if o in ('-c','--dump-conf'):
options.append('-c')
if o in ('-d','--doctype'):
doctype = v
+# config.cmd_attrs['doctype'] = v
if o in ('-e','--no-conf'):
options.append('-e')
if o in ('-f','--conf-file'):
@@ -5488,9 +5543,9 @@ def execute(cmd,opts,args):
if len(args) == 0:
usage('No source file specified')
sys.exit(1)
- if not backend:
- usage('No --backend option specified')
- sys.exit(1)
+# if not backend:
+# usage('No --backend option specified')
+# sys.exit(1)
stdin,stdout = sys.stdin,sys.stdout
try:
infile = args[0]
diff --git a/doc/asciidoc.txt b/doc/asciidoc.txt
index 51eb9e6..deb4751 100644
--- a/doc/asciidoc.txt
+++ b/doc/asciidoc.txt
@@ -2,6 +2,9 @@ AsciiDoc User Guide
===================
Stuart Rackham <srackham@gmail.com>
:Author Initials: SJR
+:toc:
+:icons:
+:numbered:
AsciiDoc is a text document format for writing documentation,
articles, manuals, books and UNIX man pages. AsciiDoc files can be
@@ -296,11 +299,9 @@ revision information:
- The Header is optional, but if it is used it must start with a
document <<X17,title>>.
-- The header can be preceded by comments and <<X18,attribute
- entries>>.
+- The header can include comments and <<X18,attribute entries>>.
- Optional Author and Revision information immediately follows the
header title.
-- The header can include attribute entries.
- The document header must be separated from the remainder of the
document by one or more blank lines.
@@ -344,7 +345,7 @@ line. The revision information can be one of two formats:
will be dropped.
* If a revision remark is specified it must be preceded by a colon.
The revision remark extends from the colon up to the next blank
- line or attribute entry and is subject to normal text
+ line, attribute entry or comment and is subject to normal text
substitutions.
* If a revision number or remark has been set but the revision date
has not been set then the revision date is set to the value of the
@@ -2473,9 +2474,7 @@ These examples illustrate the two forms of conditional inclusion. The
only difference between them is that the first is evaluated at program
load time while the second is evaluated when the output is written:
- ifdef::world[]
- Hello World!
- endif::world[]
+ ifdef::world[Hello World!]
{world#}Hello World!
@@ -2485,18 +2484,16 @@ is not defined the whole line is dropped.
The subtle difference between the two types of conditional inclusion
has implications for AsciiDoc configuration files: AsciiDoc has to
-read the configuration files *before* reading the source document,
+read the configuration files *before* writing the output document,
this is necessary because the AsciiDoc source syntax is mostly defined
-by the configuration files. This means that any lines of markup
-enveloped by conditional inclusion macros will be included or excluded
-*before* the attribute entries in the AsciiDoc document header are
-read, so setting related attributes in the AsciiDoc source document
-header will have no effect. If you need to control configuration file
-markup inclusion with attribute entries in the AsciiDoc source file
-header you need to use attribute references to control inclusion
-instead of conditional inclusion macros (attribute references are
-substituted at the time the output is written rather than at program
-startup).
+by the configuration files. This means that any AsciiDoc attributes
+set *after the source file header* will not affect conditional
+inclusion macro expansion defined inside configuration files. If you
+need to control configuration file markup inclusion with attribute
+entries in the body of the AsciiDoc source file you need to use
+attribute references to control inclusion instead of conditional
+inclusion macros (attribute references are substituted at the time the
+output is written rather than at program startup).
*********************************************************************
Executable system macros
@@ -3606,11 +3603,10 @@ Configuration File Names and Locations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Configuration files have a `.conf` file name extension; they are
loaded implicitly (using predefined file names and locations) or
-explicitly (using the asciidoc(1) `-f` (`--conf-file`) command-line
-option).
+explicitly (using the asciidoc(1) `--conf-file`) command-line option).
-Implicit configuration files are loaded from the following directories
-in the following order:
+Implicit configuration files are loaded from the following
+locations:
1. The directory containing the asciidoc executable.
2. If there is no `asciidoc.conf` file in the directory containing the
@@ -3623,43 +3619,54 @@ in the following order:
3. The user's `$HOME/.asciidoc` directory (if it exists).
4. The directory containing the AsciiDoc source file.
-The following implicit configuration files from each of the above
-locations are loaded in the following order:
+Implicit configuration files from the above locations are loaded in
+the following order:
+
+- `asciidoc.conf` from locations 1, 2, 3.
+- The document header is parsed at this point.
+- `<backend>.conf` and `<backend>-<doctype>.conf` from locations 1,
+ 2,3.
+- Filter conf files from the `filters` directory in locations 1, 2, 3.
+- `lang-<lang>.conf` from locations 1, 2, 3.
+- `asciidoc.conf` from location 4.
+- `<backend>.conf` and `<backend>-<doctype>.conf` from location 4.
+ 2,3.
+- Filter conf files from location 4.
+- `<docfile>.conf` and `<docfile>-<backend>.conf` from location 4.
+- Configuration files specified by asciidoc(1) `--conf-file`
+ command-line options. The `--conf-file` option can be specified
+ multiple times, in which case configuration files will be processed
+ in the order they appear on the command-line.
-1. `asciidoc.conf`
-2. `<backend>.conf`
-3. `<backend>-<doctype>.conf`
-
-Where `<backend>` and `<doctype>` are values specified by the
-asciidoc(1) `-b` (`--backend`) and `-d` (`--doctype`) command-line
-options.
+Where:
-Next, configuration files named like the source file will be
-automatically loaded if they are found in the source file directory.
-For example if the source file is `mydoc.txt` and the
-`--backend=html4` option is used then asciidoc(1) will look for
-`mydoc.conf` and `mydoc-html4.conf` in that order.
+- `<backend>` and `<doctype>` are values specified by the asciidoc(1)
+ `-b` (`--backend`) and `-d` (`--doctype`) command-line options.
+- `<infile>` is the path name of the AsciiDoc input file without the
+ file name extension.
+- `<lang>` is a two letter country code set by the the AsciiDoc 'lang'
+ attribute.
Implicit configuration files that don't exist will be silently
skipped.
-The user can explicitly specify additional configuration files using
-the asciidoc(1) `-f` (`--conf-file`) command-line option. The `-f`
-option can be specified multiple times, in which case configuration
-files will be processed in the order they appear on the command-line.
-
-For example, when we translate our AsciiDoc document `mydoc.txt` with:
-
- $ asciidoc -f extra.conf mydoc.txt
-
-The last configuration file to load is the language configuration file
-`lang-<lang>.conf`. `<lang>` is the value of the AsciiDoc `lang`
-attribute (defaults to `en` (English)). You can set the `lang`
-attribute inside the AsciiDoc source file using an
-<<X18,AttributeEntry>> provided it is the first entry and provided it
-precedes the document header, for example:
+[NOTE]
+=====================================================================
+The important point to take away is that backend and language global
+configuration files are loaded *after* the header has been parsed.
+This means that you can set just about any attribute in the document
+header. Here's an example header:
+
+ Life's Mysteries
+ ================
+ :author: Hu Nose
+ :doctype: book
+ :toc:
+ :icons:
+ :data-uri:
+ :lang: en
- :lang: es
+=====================================================================
TIP: Use the asciidoc(1) `-v` (`--verbose`) command-line option to see
which configuration files are loaded and the order in which they are
diff --git a/docbook45.conf b/docbook45.conf
index 8a5c197..a594a91 100644
--- a/docbook45.conf
+++ b/docbook45.conf
@@ -14,6 +14,9 @@ pageunits=*
[attributes]
basebackend=docbook
basebackend-docbook=
+basebackend-docbook45=
+# For backward compatibility (docbook backend was renamed to docbook45 at 8.6.2)
+backend-docbook=
# toc and numbered are set to maintain original default behavior.
toc=
numbered=
diff --git a/filters/graphviz/graphviz-filter.conf b/filters/graphviz/graphviz-filter.conf
index e735aee..d658e25 100644
--- a/filters/graphviz/graphviz-filter.conf
+++ b/filters/graphviz/graphviz-filter.conf
@@ -14,7 +14,7 @@ graphviz-style=template="graphviz{format?-{format}}-block",subs=(),posattrs=("st
template::[filter-image-blockmacro]
# EXPERIMENTAL: xhtml11 backend SVG image block.
-ifdef::backend-xhtml11[]
+ifdef::basebackend-xhtml11[]
[graphviz-svg-block]
<div class="imageblock"{id? id="{id}"}{align? style="text-align:{align};"}{float? style="float:{float};"}>
<div class="content">
@@ -24,7 +24,7 @@ ifdef::backend-xhtml11[]
</div>
<div class="title">{caption={figure-caption} {counter:figure-number}. }{title}</div>
</div>
-endif::backend-xhtml11[]
+endif::basebackend-xhtml11[]
#
# DEPRECATED: Pre 8.2.7 filter definition.
diff --git a/filters/source/source-highlight-filter.conf b/filters/source/source-highlight-filter.conf
index f89aca2..ee0107a 100644
--- a/filters/source/source-highlight-filter.conf
+++ b/filters/source/source-highlight-filter.conf
@@ -30,7 +30,7 @@ ifdef::basebackend-html[]
endif::basebackend-html[]
# Customized listingblock block for xhtml11 to ensure valid XHTML1.1.
-ifdef::backend-xhtml11[]
+ifdef::basebackend-xhtml11[]
[source-highlight-block]
<div class="listingblock">
<a id="{id}"></a>
@@ -38,7 +38,7 @@ ifdef::backend-xhtml11[]
<div class="content">
|
</div></div>
-endif::backend-xhtml11[]
+endif::basebackend-xhtml11[]
# Use DocBook programlisting element.
ifdef::basebackend-docbook[]
@@ -58,10 +58,10 @@ ifdef::basebackend-html[]
source-style=template="source-highlight-block",presubs=(),postsubs=("callouts",),posattrs=("style","language","src_numbered","src_tab"),filter="source-highlight -f html -s {language} {src_numbered?--line-number} {src_tab?--tab={src_tab}}"
endif::basebackend-html[]
-ifdef::backend-xhtml11[]
+ifdef::basebackend-xhtml11[]
ifndef::pygments[source-style=template="source-highlight-block",presubs=(),postsubs=("callouts",),posattrs=("style","language","src_numbered","src_tab"),filter="source-highlight -f xhtml -s {language} {src_numbered?--line-number} {src_tab?--tab={src_tab}}"]
ifdef::pygments[source-style=template="source-highlight-block",presubs=(),postsubs=("callouts",),posattrs=("style","language","src_numbered"),filter="pygmentize -f html -l {language} {src_numbered?-O linenos=table}"]
-endif::backend-xhtml11[]
+endif::basebackend-xhtml11[]
ifdef::basebackend-docbook[]
source-style=template="source-highlight-block",presubs=(),postsubs=("specialcharacters","callouts"),posattrs=("style","language","src_numbered","src_tab"),filter=""
@@ -75,10 +75,10 @@ ifdef::basebackend-html[]
source-style=template="source-highlight-block",presubs=(),postsubs=("callouts",),posattrs=("style","language","src_numbered","src_tab"),filter="source-highlight -f html -s {language} {src_numbered?--line-number} {src_tab?--tab={src_tab}}"
endif::basebackend-html[]
-ifdef::backend-xhtml11[]
+ifdef::basebackend-xhtml11[]
ifndef::pygments[source-style=template="source-highlight-block",presubs=(),postsubs=("callouts",),posattrs=("style","language","src_numbered","src_tab"),filter="source-highlight -f xhtml -s {language} {src_numbered?--line-number} {src_tab?--tab={src_tab}}"]
ifdef::pygments[source-style=template="source-highlight-block",presubs=(),postsubs=("callouts",),posattrs=("style","language","src_numbered"),filter="pygmentize -f html -l {language} {src_numbered?-O linenos=table}"]
-endif::backend-xhtml11[]
+endif::basebackend-xhtml11[]
ifdef::basebackend-docbook[]
source-style=template="source-highlight-block",presubs=(),postsubs=("specialcharacters","callouts"),posattrs=("style","language","src_numbered","src_tab")
@@ -103,7 +103,7 @@ posattrs=language,src_numbered,src_tab
ifndef::basebackend-docbook[]
postsubs=callouts
# GNU Source Highlight filter.
-filter=source-highlight -f {backend-xhtml11?xhtml}{backend-html4?html} -s {language} {src_numbered?--line-number} {src_tab?--tab={src_tab}}
+filter=source-highlight -f {basebackend-xhtml11?xhtml}{basebackend-html4?html} -s {language} {src_numbered?--line-number} {src_tab?--tab={src_tab}}
endif::basebackend-docbook[]
ifdef::basebackend-docbook[]
diff --git a/html4.conf b/html4.conf
index 7762ed3..4a38441 100644
--- a/html4.conf
+++ b/html4.conf
@@ -10,6 +10,7 @@ outfilesuffix=.html
[attributes]
basebackend=html
basebackend-html=
+basebackend-html4=
[replacements2]
# Line break.
diff --git a/lang-de.conf b/lang-de.conf
index 88c1872..a3ff367 100644
--- a/lang-de.conf
+++ b/lang-de.conf
@@ -22,7 +22,7 @@ appendix-caption=Anhang
manname-title=NAME
[footer-text]
-Version {revnumber}{backend@xhtml11:<br />:<br>}
+Version {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
Letzte Änderung {docdate} {doctime}
endif::basebackend-html[]
diff --git a/lang-en.conf b/lang-en.conf
index 5b9dfd0..9d1c6d4 100644
--- a/lang-en.conf
+++ b/lang-en.conf
@@ -21,7 +21,7 @@ appendix-caption=Appendix
manname-title=NAME
[footer-text]
-Version {revnumber}{backend@xhtml11:<br />:<br>}
+Version {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
Last updated {docdate} {doctime}
endif::basebackend-html[]
diff --git a/lang-es.conf b/lang-es.conf
index 62ce3a8..3b4b214 100644
--- a/lang-es.conf
+++ b/lang-es.conf
@@ -22,7 +22,7 @@ manname-title=NOMBRE DE REFERENCIA
[footer-text]
#TODO: Translation of 'Version' and 'Last updated'.
-Version {revnumber}{backend@xhtml11:<br />:<br>}
+Version {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
Last updated {docdate} {doctime}
endif::basebackend-html[]
diff --git a/lang-fr.conf b/lang-fr.conf
index 9ef9cfc..d860132 100644
--- a/lang-fr.conf
+++ b/lang-fr.conf
@@ -22,7 +22,7 @@ appendix-caption=Appendice
manname-title=NOM
[footer-text]
-Version {revnumber}{backend@xhtml11:<br />:<br>}
+Version {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
Dernière mise à jour {docdate} {doctime}
endif::basebackend-html[]
diff --git a/lang-hu.conf b/lang-hu.conf
index 2f294ac..1cda948 100644
--- a/lang-hu.conf
+++ b/lang-hu.conf
@@ -22,7 +22,7 @@ appendix-caption=függelék
manname-title=NÉV
[footer-text]
-Verzió {revnumber}{backend@xhtml11:<br />:<br>}
+Verzió {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
Utolsó frissítés: {docdate} {doctime}
endif::basebackend-html[]
diff --git a/lang-it.conf b/lang-it.conf
index 7e70b65..9c08f45 100644
--- a/lang-it.conf
+++ b/lang-it.conf
@@ -22,7 +22,7 @@ manname-title=NOME
[footer-text]
#TODO: Translation of 'Version' and 'Last updated'.
-Version {revnumber}{backend@xhtml11:<br />:<br>}
+Version {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
Last updated {docdate} {doctime}
endif::basebackend-html[]
diff --git a/lang-pt-BR.conf b/lang-pt-BR.conf
index 74f8e36..cfb4c31 100644
--- a/lang-pt-BR.conf
+++ b/lang-pt-BR.conf
@@ -23,7 +23,7 @@ manname-title=NOME
[footer-text]
#TODO: Translation of 'Version' and 'Last updated'.
-Version {revnumber}{backend@xhtml11:<br />:<br>}
+Version {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
Last updated {docdate} {doctime}
endif::basebackend-html[]
diff --git a/lang-ru.conf b/lang-ru.conf
index 7255a56..5ce4db0 100644
--- a/lang-ru.conf
+++ b/lang-ru.conf
@@ -23,7 +23,7 @@ manname-title=ИМЯ
[footer-text]
#TODO: Translation of 'Version' and 'Last updated'.
-Version {revnumber}{backend@xhtml11:<br />:<br>}
+Version {revnumber}{basebackend-xhtml11?<br />}{basebackend-xhtml11=<br>}
Last updated {docdate} {doctime}
endif::basebackend-html[]
diff --git a/tests/data/lang-de-test.txt b/tests/data/lang-de-test.txt
index b0e419a..ebddb62 100644
--- a/tests/data/lang-de-test.txt
+++ b/tests/data/lang-de-test.txt
@@ -3,6 +3,8 @@
Languages Test
==============
+:revnumber: v1.0
+:revdate: 2003-12-21
ifdef::doctype-article[]
Zusammenfassung
@@ -93,7 +95,7 @@ A second glossary term::
The corresponding (indented) definition.
-ifdef::backend-docbook[]
+ifdef::basebackend-docbook[]
Stichwortverzeichnis
--------------------
////////////////////////////////////////////////////////////////
@@ -101,4 +103,4 @@ Index special section.
The index is normally left completely empty, it's contents being
generated automatically by the DocBook toolchain.
////////////////////////////////////////////////////////////////
-endif::backend-docbook[]
+endif::basebackend-docbook[]
diff --git a/tests/data/lang-en-test.txt b/tests/data/lang-en-test.txt
index 3489d64..a312458 100644
--- a/tests/data/lang-en-test.txt
+++ b/tests/data/lang-en-test.txt
@@ -3,6 +3,8 @@
Languages Test
==============
+:revnumber: v1.0
+:revdate: 2003-12-21
ifdef::doctype-article[]
// Translate title.
@@ -100,7 +102,7 @@ A second glossary term::
The corresponding (indented) definition.
-ifdef::backend-docbook[]
+ifdef::basebackend-docbook[]
// Translate title.
Index
-----
@@ -109,4 +111,4 @@ Index special section.
The index is normally left completely empty, it's contents being
generated automatically by the DocBook toolchain.
////////////////////////////////////////////////////////////////
-endif::backend-docbook[]
+endif::basebackend-docbook[]
diff --git a/tests/data/lang-es-test.txt b/tests/data/lang-es-test.txt
index 5fa2823..97eca94 100644
--- a/tests/data/lang-es-test.txt
+++ b/tests/data/lang-es-test.txt
@@ -3,6 +3,8 @@
Languages Test
==============
+:revnumber: v1.0
+:revdate: 2003-12-21
ifdef::doctype-article[]
Resumen
@@ -93,7 +95,7 @@ A second glossary term::
The corresponding (indented) definition.
-ifdef::backend-docbook[]
+ifdef::basebackend-docbook[]
Índice
------
////////////////////////////////////////////////////////////////
@@ -101,4 +103,4 @@ Index special section.
The index is normally left completely empty, it's contents being
generated automatically by the DocBook toolchain.
////////////////////////////////////////////////////////////////
-endif::backend-docbook[]
+endif::basebackend-docbook[]
diff --git a/tests/data/lang-fr-test.txt b/tests/data/lang-fr-test.txt
index 994884d..84c25fa 100644
--- a/tests/data/lang-fr-test.txt
+++ b/tests/data/lang-fr-test.txt
@@ -3,6 +3,8 @@
Languages Test
==============
+:revnumber: v1.0
+:revdate: 2003-12-21
ifdef::doctype-article[]
Résumé
@@ -93,7 +95,7 @@ A second glossary term::
The corresponding (indented) definition.
-ifdef::backend-docbook[]
+ifdef::basebackend-docbook[]
Index
-----
////////////////////////////////////////////////////////////////
@@ -101,4 +103,4 @@ Index special section.
The index is normally left completely empty, it's contents being
generated automatically by the DocBook toolchain.
////////////////////////////////////////////////////////////////
-endif::backend-docbook[]
+endif::basebackend-docbook[]
diff --git a/tests/data/lang-hu-test.txt b/tests/data/lang-hu-test.txt
index 40ab6bd..cf873c2 100644
--- a/tests/data/lang-hu-test.txt
+++ b/tests/data/lang-hu-test.txt
@@ -3,6 +3,8 @@
Languages Test
==============
+:revnumber: v1.0
+:revdate: 2003-12-21
ifdef::doctype-article[]
Kivonat
@@ -93,7 +95,7 @@ A second glossary term::
The corresponding (indented) definition.
-ifdef::backend-docbook[]
+ifdef::basebackend-docbook[]
Index
-----
////////////////////////////////////////////////////////////////
@@ -101,4 +103,4 @@ Index special section.
The index is normally left completely empty, it's contents being
generated automatically by the DocBook toolchain.
////////////////////////////////////////////////////////////////
-endif::backend-docbook[]
+endif::basebackend-docbook[]
diff --git a/tests/data/lang-pt-BR-test.txt b/tests/data/lang-pt-BR-test.txt
index e143822..daaff18 100644
--- a/tests/data/lang-pt-BR-test.txt
+++ b/tests/data/lang-pt-BR-test.txt
@@ -3,6 +3,8 @@
Languages Test
==============
+:revnumber: v1.0
+:revdate: 2003-12-21
ifdef::doctype-article[]
Resumo
@@ -93,7 +95,7 @@ A second glossary term::
The corresponding (indented) definition.
-ifdef::backend-docbook[]
+ifdef::basebackend-docbook[]
Índice
------
////////////////////////////////////////////////////////////////
@@ -101,4 +103,4 @@ Index special section.
The index is normally left completely empty, it's contents being
generated automatically by the DocBook toolchain.
////////////////////////////////////////////////////////////////
-endif::backend-docbook[]
+endif::basebackend-docbook[]
diff --git a/tests/data/lang-ru-test.txt b/tests/data/lang-ru-test.txt
index eed6fd5..51d9b60 100644
--- a/tests/data/lang-ru-test.txt
+++ b/tests/data/lang-ru-test.txt
@@ -3,6 +3,8 @@
Languages Test
==============
+:revnumber: v1.0
+:revdate: 2003-12-21
ifdef::doctype-article[]
Аннотация
@@ -93,7 +95,7 @@ A second glossary term::
The corresponding (indented) definition.
-ifdef::backend-docbook[]
+ifdef::basebackend-docbook[]
Предметный указатель
--------------------
////////////////////////////////////////////////////////////////
@@ -101,4 +103,4 @@ Index special section.
The index is normally left completely empty, it's contents being
generated automatically by the DocBook toolchain.
////////////////////////////////////////////////////////////////
-endif::backend-docbook[]
+endif::basebackend-docbook[]
diff --git a/tests/data/testcases.txt b/tests/data/testcases.txt
index c3a918a..4290e1a 100644
--- a/tests/data/testcases.txt
+++ b/tests/data/testcases.txt
@@ -389,7 +389,7 @@ This is a *bold* a line
This is a 'strong' line
This is another _strong_ line
-ifndef::backend-docbook[]
+ifndef::basebackend-docbook[]
.Monospaced paragraph with line breaks
+This is a *bold* line+ +
+This is a 'strong' line+ +
@@ -401,7 +401,7 @@ ifndef::backend-docbook[]
This is a 'strong' line +
This is another _strong_ line+
-endif::backend-docbook[]
+endif::basebackend-docbook[]
.Literal block with quotes substitution
[subs="quotes"]
diff --git a/tests/testasciidoc.conf b/tests/testasciidoc.conf
index dfe9b25..9c37b27 100644
--- a/tests/testasciidoc.conf
+++ b/tests/testasciidoc.conf
@@ -171,7 +171,7 @@ data/utf8-examples.txt
English language file (article)
% backends
-['docbook','xhtml11']
+['docbook','xhtml11','html4']
% name
lang-en-article-test
@@ -189,7 +189,7 @@ data/lang-en-test.txt
English language file (book)
% backends
-['docbook','xhtml11']
+['docbook','xhtml11','html4']
% name
lang-en-book-test
diff --git a/xhtml11.conf b/xhtml11.conf
index 9d85042..77ca66f 100644
--- a/xhtml11.conf
+++ b/xhtml11.conf
@@ -11,6 +11,7 @@ outfilesuffix=.html
[attributes]
basebackend=html
basebackend-html=
+basebackend-xhtml11=
[replacements2]
# Line break.
@@ -606,13 +607,15 @@ endif::latexmath[]
# Article, book header.
ifndef::doctype-manpage[]
<div id="header">
-{notitle%}<h1>{doctitle}</h1>
-{doctitle#}<span id="author">{author}</span><br />
-{doctitle#}<span id="email"><tt>&lt;<a href="mailto:{email}">{email}</a>&gt;</tt></span><br />
-{doctitle#}<span id="revnumber">version {revnumber}{revdate?,}</span>
-{doctitle#}<span id="revdate">{revdate}</span>
-{doctitle#}<br /><span id="revremark">{revremark}</span>
-{toc#}{template:toc}
+ifndef::notitle[<h1>{doctitle}</h1>]
+ifdef::doctitle[]
+<span id="author">{author}</span><br />
+<span id="email"><tt>&lt;<a href="mailto:{email}">{email}</a>&gt;</tt></span><br />
+<span id="revnumber">version {revnumber}{revdate?,}</span>
+<span id="revdate">{revdate}</span>
+<br /><span id="revremark">{revremark}</span>
+endif::doctitle[]
+ifdef::toc[{template:toc}]
</div>
endif::doctype-manpage[]
# Man page header.
@@ -621,7 +624,7 @@ ifdef::doctype-manpage[]
<h1>
{doctitle} Manual Page
</h1>
-{toc#}{template:toc}
+ifdef::toc[{template:toc}]
<h2>{manname-title}</h2>
<div class="sectionbody">
<p>{manname} -