diff options
author | Stuart Rackham <srackham@methods.co.nz> | 2010-09-28 16:08:57 +1300 |
---|---|---|
committer | Stuart Rackham <srackham@methods.co.nz> | 2010-09-28 16:08:57 +1300 |
commit | c2f943bcaabf71e53535ef2a2101a2cf5cb0f347 (patch) | |
tree | 43d5fac58f2c686a2064d5cf7b7a00e9ca0212be | |
parent | 065b605f6b0d04877215099633ff30a372fc8527 (diff) | |
download | asciidoc-c2f943bcaabf71e53535ef2a2101a2cf5cb0f347.tar.gz |
Backend specific global configuration files (excluding `asciidoc.conf`) are
loaded *after* the header has been parsed.
-rwxr-xr-x | asciidoc.py | 357 | ||||
-rw-r--r-- | doc/asciidoc.txt | 111 | ||||
-rw-r--r-- | docbook45.conf | 3 | ||||
-rw-r--r-- | filters/graphviz/graphviz-filter.conf | 4 | ||||
-rw-r--r-- | filters/source/source-highlight-filter.conf | 14 | ||||
-rw-r--r-- | html4.conf | 1 | ||||
-rw-r--r-- | lang-de.conf | 2 | ||||
-rw-r--r-- | lang-en.conf | 2 | ||||
-rw-r--r-- | lang-es.conf | 2 | ||||
-rw-r--r-- | lang-fr.conf | 2 | ||||
-rw-r--r-- | lang-hu.conf | 2 | ||||
-rw-r--r-- | lang-it.conf | 2 | ||||
-rw-r--r-- | lang-pt-BR.conf | 2 | ||||
-rw-r--r-- | lang-ru.conf | 2 | ||||
-rw-r--r-- | tests/data/lang-de-test.txt | 6 | ||||
-rw-r--r-- | tests/data/lang-en-test.txt | 6 | ||||
-rw-r--r-- | tests/data/lang-es-test.txt | 6 | ||||
-rw-r--r-- | tests/data/lang-fr-test.txt | 6 | ||||
-rw-r--r-- | tests/data/lang-hu-test.txt | 6 | ||||
-rw-r--r-- | tests/data/lang-pt-BR-test.txt | 6 | ||||
-rw-r--r-- | tests/data/lang-ru-test.txt | 6 | ||||
-rw-r--r-- | tests/data/testcases.txt | 4 | ||||
-rw-r--r-- | tests/testasciidoc.conf | 4 | ||||
-rw-r--r-- | xhtml11.conf | 19 |
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[] @@ -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><<a href="mailto:{email}">{email}</a>></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><<a href="mailto:{email}">{email}</a>></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} -
|