updated from Docutils

This commit is contained in:
David Goodger 2002-11-17 00:09:20 +00:00
parent 4e06fbde27
commit 461747e153
7 changed files with 153 additions and 39 deletions

View File

@ -122,29 +122,37 @@ _directives = {}
def directive(directive_name, language_module, document): def directive(directive_name, language_module, document):
""" """
Locate and return a directive function from its language-dependent name. Locate and return a directive function from its language-dependent name.
If not found in the current language, check English. If not found in the current language, check English. Return None if the
named directive cannot be found.
""" """
normname = directive_name.lower() normname = directive_name.lower()
messages = [] messages = []
msg_text = []
if _directives.has_key(normname): if _directives.has_key(normname):
return _directives[normname], messages return _directives[normname], messages
canonicalname = None
try: try:
canonicalname = language_module.directives[normname] canonicalname = language_module.directives[normname]
except (KeyError, AttributeError): except AttributeError, error:
msg_text = ('No directive entry for "%s" in module "%s".' msg_text.append('Problem retrieving directive entry from language '
'module %r: %s.' % (language_module, error))
except KeyError:
msg_text.append('No directive entry for "%s" in module "%s".'
% (directive_name, language_module.__name__)) % (directive_name, language_module.__name__))
if not canonicalname:
try: try:
canonicalname = _fallback_language_module.directives[normname] canonicalname = _fallback_language_module.directives[normname]
msg_text += ('\nUsing English fallback for directive "%s".' msg_text.append('Using English fallback for directive "%s".'
% directive_name) % directive_name)
except KeyError: except KeyError:
msg_text += ('\nTrying "%s" as canonical directive name.' msg_text.append('Trying "%s" as canonical directive name.'
% directive_name) % directive_name)
# The canonical name should be an English name, but just in case: # The canonical name should be an English name, but just in case:
canonicalname = normname canonicalname = normname
warning = document.reporter.warning( if msg_text:
msg_text, line=document.current_line) message = document.reporter.info(
messages.append(warning) '\n'.join(msg_text), line=document.current_line)
messages.append(message)
try: try:
modulename, functionname = _directive_registry[canonicalname] modulename, functionname = _directive_registry[canonicalname]
except KeyError: except KeyError:

View File

@ -16,6 +16,9 @@ _languages = {}
def get_language(language_code): def get_language(language_code):
if _languages.has_key(language_code): if _languages.has_key(language_code):
return _languages[language_code] return _languages[language_code]
try:
module = __import__(language_code, globals(), locals()) module = __import__(language_code, globals(), locals())
except ImportError:
return None
_languages[language_code] = module _languages[language_code] = module
return module return module

View File

@ -0,0 +1,46 @@
# Author: Miroslav Vasko
# Contact: zemiak@zoznam.sk
# Revision: $Revision$
# Date: $Date$
# Copyright: This module has been placed in the public domain.
"""
Slovak-language mappings for language-dependent features of
reStructuredText.
"""
__docformat__ = 'reStructuredText'
directives = {
u'pozor': 'attention',
u'opatrne': 'caution',
u'nebezpe\xe8enstvo': 'danger',
u'chyba': 'error',
u'rada': 'hint',
u'd\xf4le\x9eit\xe9': 'important',
u'pozn\xe1mka': 'note',
u'tip': 'tip',
u'varovanie': 'warning',
u't\xe9ma': 'topic',
u'blok-riadkov': 'line-block',
u'parsed-literal': 'parsed-literal',
#u'questions': 'questions',
#u'qa': 'questions',
#u'faq': 'questions',
u'meta': 'meta',
#u'imagemap': 'imagemap',
u'obr\xe1zok': 'image',
u'tvar': 'figure',
u'vlo\x9ei\x9d': 'include',
u'raw': 'raw',
u'nahradi\x9d': 'replace',
u'obsah': 'contents',
u'\xe8as\x9d': 'sectnum',
u'\xe8as\x9d-\xe8\xedslovanie': 'sectnum',
u'cie\xbeov\xe9-pozn\xe1mky': 'target-notes',
#u'footnotes': 'footnotes',
#u'citations': 'citations',
}
"""Slovak name to registered (in directives/__init__.py) directive name
mapping."""

View File

@ -21,19 +21,18 @@ directives = {
u'notera': 'note', u'notera': 'note',
u'tips': 'tip', u'tips': 'tip',
u'varning': 'warning', u'varning': 'warning',
u'fr\u00e5gor': 'questions', # u'fr\u00e5gor': 'questions',
# NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/: # NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/:
u'fr\u00e5gor-och-svar': 'questions', # u'fr\u00e5gor-och-svar': 'questions',
u'vanliga-fr\u00e5gor': 'questions', # u'vanliga-fr\u00e5gor': 'questions',
u'meta': 'meta', u'meta': 'meta',
# u'bildkarta': 'imagemap', # FIXME: Translation might be too literal. # u'bildkarta': 'imagemap', # FIXME: Translation might be too literal.
u'bild': 'image', u'bild': 'image',
u'figur': 'figure', u'figur': 'figure',
# u'r\u00e5': 'raw', # FIXME: Translation might be too literal. u'r\u00e5': 'raw', # FIXME: Translation might be too literal.
u'inneh\u00e5ll': 'contents', u'inneh\u00e5ll': 'contents',
# u'fotnoter': 'footnotes', # u'fotnoter': 'footnotes',
# u'citeringar': 'citations', # u'citeringar': 'citations',
# u'\u00e4mne': 'topic', u'\u00e4mne': 'topic'}
u'restructuredtext-test-directive': 'restructuredtext-test-directive' }
"""Swedish name to registered (in directives/__init__.py) directive name """Swedish name to registered (in directives/__init__.py) directive name
mapping.""" mapping."""

View File

@ -534,9 +534,17 @@ class Inliner:
non_whitespace_after = r'(?![ \n])' non_whitespace_after = r'(?![ \n])'
# Alphanumerics with isolated internal [-._] chars (i.e. not 2 together): # Alphanumerics with isolated internal [-._] chars (i.e. not 2 together):
simplename = r'(?:(?!_)\w)+(?:[-._](?:(?!_)\w)+)*' simplename = r'(?:(?!_)\w)+(?:[-._](?:(?!_)\w)+)*'
# Valid URI characters (see RFC 2396 & RFC 2732):
uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]""" uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]"""
urilast = r"""[_~/\]a-zA-Z0-9]""" # no punctuation # Last URI character; same as uric but no punctuation:
urilast = r"""[_~/a-zA-Z0-9]"""
emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]""" emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]"""
email_pattern = r"""
%(emailc)s+(?:\.%(emailc)s+)* # name
@ # at
%(emailc)s+(?:\.%(emailc)s*)* # host
%(urilast)s # final URI char
"""
parts = ('initial_inline', start_string_prefix, '', parts = ('initial_inline', start_string_prefix, '',
[('start', '', non_whitespace_after, # simple start-strings [('start', '', non_whitespace_after, # simple start-strings
[r'\*\*', # strong [r'\*\*', # strong
@ -581,6 +589,18 @@ class Inliner:
) )
%(end_string_suffix)s %(end_string_suffix)s
""" % locals(), re.VERBOSE | re.UNICODE), """ % locals(), re.VERBOSE | re.UNICODE),
embedded_uri=re.compile(
r"""
(
[ \n]+ # spaces or beginning of line
< # open bracket
%(non_whitespace_after)s
([^<>\0]+) # anything but angle brackets & nulls
%(non_whitespace_before)s
> # close bracket w/o whitespace before
)
$ # end of string
""" % locals(), re.VERBOSE),
literal=re.compile(non_whitespace_before + '(``)' literal=re.compile(non_whitespace_before + '(``)'
+ end_string_suffix), + end_string_suffix),
target=re.compile(non_whitespace_escape_before target=re.compile(non_whitespace_escape_before
@ -588,8 +608,9 @@ class Inliner:
substitution_ref=re.compile(non_whitespace_escape_before substitution_ref=re.compile(non_whitespace_escape_before
+ r'(\|_{0,2})' + r'(\|_{0,2})'
+ end_string_suffix), + end_string_suffix),
email=re.compile(email_pattern % locals() + '$', re.VERBOSE),
uri=re.compile( uri=re.compile(
r""" (r"""
%(start_string_prefix)s %(start_string_prefix)s
(?P<whole> (?P<whole>
(?P<absolute> # absolute URI (?P<absolute> # absolute URI
@ -615,14 +636,11 @@ class Inliner:
) )
| # *OR* | # *OR*
(?P<email> # email address (?P<email> # email address
%(emailc)s+(\.%(emailc)s+)* # name """ + email_pattern + r"""
@ # at
%(emailc)s+(\.%(emailc)s*)* # host
%(urilast)s # final URI char
) )
) )
%(end_string_suffix)s %(end_string_suffix)s
""" % locals(), re.VERBOSE), """) % locals(), re.VERBOSE),
pep=re.compile( pep=re.compile(
r""" r"""
%(start_string_prefix)s %(start_string_prefix)s
@ -736,7 +754,7 @@ class Inliner:
prb = self.problematic(text, text, msg) prb = self.problematic(text, text, msg)
return string[:rolestart], [prb], string[textend:], [msg] return string[:rolestart], [prb], string[textend:], [msg]
return self.phrase_ref(string[:matchstart], string[textend:], return self.phrase_ref(string[:matchstart], string[textend:],
rawsource, text) rawsource, escaped, text)
else: else:
return self.interpreted(string[:rolestart], string[textend:], return self.interpreted(string[:rolestart], string[textend:],
rawsource, text, role, position) rawsource, text, role, position)
@ -747,16 +765,46 @@ class Inliner:
prb = self.problematic(text, text, msg) prb = self.problematic(text, text, msg)
return string[:matchstart], [prb], string[matchend:], [msg] return string[:matchstart], [prb], string[matchend:], [msg]
def phrase_ref(self, before, after, rawsource, text): def phrase_ref(self, before, after, rawsource, escaped, text):
match = self.patterns.embedded_uri.search(escaped)
if match:
text = unescape(escaped[:match.start(0)])
uri_text = match.group(2)
uri = ''.join(uri_text.split())
uri = self.adjust_uri(uri)
if uri:
target = nodes.target(match.group(1), refuri=uri)
else:
raise ApplicationError('problem with URI: %r' % uri_text)
else:
target = None
refname = normalize_name(text) refname = normalize_name(text)
reference = nodes.reference(rawsource, text) reference = nodes.reference(rawsource, text)
node_list = [reference]
if rawsource[-2:] == '__': if rawsource[-2:] == '__':
if target:
reference['refuri'] = uri
else:
reference['anonymous'] = 1 reference['anonymous'] = 1
self.document.note_anonymous_ref(reference) self.document.note_anonymous_ref(reference)
else:
if target:
reference['refuri'] = uri
target['name'] = refname
self.document.note_external_target(target)
self.document.note_explicit_target(target, self.parent)
node_list.append(target)
else: else:
reference['refname'] = refname reference['refname'] = refname
self.document.note_refname(reference) self.document.note_refname(reference)
return before, [reference], after, [] return before, node_list, after, []
def adjust_uri(self, uri):
match = self.patterns.email.match(uri)
if match:
return 'mailto:' + uri
else:
return uri
def interpreted(self, before, after, rawsource, text, role, position): def interpreted(self, before, after, rawsource, text, role, position):
if role: if role:
@ -1639,8 +1687,12 @@ class Body(RSTState):
name = normalize_name(unescape(targetname)) name = normalize_name(unescape(targetname))
target['name'] = name target['name'] = name
if refuri: if refuri:
target['refuri'] = refuri uri = self.inliner.adjust_uri(refuri)
if uri:
target['refuri'] = uri
self.document.note_external_target(target) self.document.note_external_target(target)
else:
raise ApplicationError('problem with URI: %r' % refuri)
else: else:
self.document.note_internal_target(target) self.document.note_internal_target(target)
self.document.note_explicit_target(target, self.parent) self.document.note_explicit_target(target, self.parent)

View File

@ -170,6 +170,7 @@ class TargetNotes(Transform):
if not refsect: if not refsect:
refsect = nodes.section() refsect = nodes.section()
refsect += nodes.title('', 'References') refsect += nodes.title('', 'References')
doc.set_id(refsect)
if copyright: if copyright:
# Put the new "References" section before "Copyright": # Put the new "References" section before "Copyright":
doc.insert(copyright, refsect) doc.insert(copyright, refsect)

View File

@ -134,12 +134,13 @@ class HTMLTranslator(nodes.NodeVisitor):
option) disables list whitespace optimization. option) disables list whitespace optimization.
""" """
xml_declaration = '<?xml version="1.0" encoding="%s"?>\n' xml_declaration = '<?xml version="1.0" encoding="%s" ?>\n'
doctype = ('<!DOCTYPE html' doctype = ('<!DOCTYPE html'
' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' ' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
' "http://www.w3.org/TR/xhtml1/DTD/' ' "http://www.w3.org/TR/xhtml1/DTD/'
'xhtml1-transitional.dtd">\n') 'xhtml1-transitional.dtd">\n')
html_head = '<html lang="%s">\n<head>\n' html_head = ('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="%s" '
'lang="%s">\n<head>\n')
content_type = ('<meta http-equiv="Content-Type" content="text/html; ' content_type = ('<meta http-equiv="Content-Type" content="text/html; '
'charset=%s" />\n') 'charset=%s" />\n')
generator = ('<meta name="generator" content="Docutils %s: ' generator = ('<meta name="generator" content="Docutils %s: '
@ -153,11 +154,12 @@ class HTMLTranslator(nodes.NodeVisitor):
def __init__(self, document): def __init__(self, document):
nodes.NodeVisitor.__init__(self, document) nodes.NodeVisitor.__init__(self, document)
self.settings = settings = document.settings self.settings = settings = document.settings
self.language = languages.get_language(settings.language_code) lcode = settings.language_code
self.language = languages.get_language(lcode)
self.head_prefix = [ self.head_prefix = [
self.xml_declaration % settings.output_encoding, self.xml_declaration % settings.output_encoding,
self.doctype, self.doctype,
self.html_head % settings.language_code, self.html_head % (lcode, lcode),
self.content_type % settings.output_encoding, self.content_type % settings.output_encoding,
self.generator % docutils.__version__] self.generator % docutils.__version__]
self.head = [] self.head = []
@ -167,7 +169,10 @@ class HTMLTranslator(nodes.NodeVisitor):
self.stylesheet = [self.embedded_stylesheet % stylesheet_text] self.stylesheet = [self.embedded_stylesheet % stylesheet_text]
else: else:
stylesheet = self.get_stylesheet_reference() stylesheet = self.get_stylesheet_reference()
if stylesheet:
self.stylesheet = [self.stylesheet_link % stylesheet] self.stylesheet = [self.stylesheet_link % stylesheet]
else:
self.stylesheet = []
self.body_prefix = ['</head>\n<body>\n'] self.body_prefix = ['</head>\n<body>\n']
self.body_pre_docinfo = [] self.body_pre_docinfo = []
self.docinfo = [] self.docinfo = []