[sgala]Do not depend on docutils if we don't use rst xhtml generator. See #316

This commit is contained in:
Yann Leboulanger 2006-10-04 11:53:03 +00:00
parent d55e56f0b9
commit 53f8b119bc
3 changed files with 84 additions and 72 deletions

View File

@ -547,7 +547,7 @@ class ChatControlBase(MessageControl):
end = True end = True
textview.print_conversation_line(text, jid, kind, name, tim, textview.print_conversation_line(text, jid, kind, name, tim,
other_tags_for_name, other_tags_for_time, other_tags_for_text, other_tags_for_name, other_tags_for_time, other_tags_for_text,
subject, old_kind, xhtml) subject, old_kind, xhtml = xhtml)
if not count_as_new: if not count_as_new:
return return
@ -1254,7 +1254,9 @@ class ChatControl(ChatControlBase):
kind = 'outgoing' kind = 'outgoing'
name = gajim.nicks[self.account] name = gajim.nicks[self.account]
if not xhtml and not encrypted and gajim.config.get('rst_formatting_outgoing_messages'): if not xhtml and not encrypted and gajim.config.get('rst_formatting_outgoing_messages'):
xhtml = '<body xmlns="%s">%s</body>' % (NS_XHTML, create_xhtml(text)) xhtml = create_xhtml(text)
if xhtml:
xhtml = '<body xmlns="%s">%s</body>' % (NS_XHTML, xhtml)
ChatControlBase.print_conversation_line(self, text, kind, name, tim, ChatControlBase.print_conversation_line(self, text, kind, name, tim,
subject = subject, old_kind = self.old_msg_kind, xhtml = xhtml) subject = subject, old_kind = self.old_msg_kind, xhtml = xhtml)
if text.startswith('/me ') or text.startswith('/me\n'): if text.startswith('/me ') or text.startswith('/me\n'):

View File

@ -678,7 +678,7 @@ class Connection(ConnectionHandlers):
user_nick = None, xhtml = None): user_nick = None, xhtml = None):
if not self.connection: if not self.connection:
return return
if not xhtml and gajim.config.get('rst_formatting_outgoing_messages'): if msg and not xhtml and gajim.config.get('rst_formatting_outgoing_messages'):
xhtml = create_xhtml(msg) xhtml = create_xhtml(msg)
if not msg and chatstate is None: if not msg and chatstate is None:
return return

View File

@ -14,88 +14,98 @@
## GNU General Public License for more details. ## GNU General Public License for more details.
## ##
from docutils import io try:
from docutils.core import Publisher from docutils import io
from docutils.parsers.rst import roles from docutils.core import Publisher
from docutils.parsers.rst import roles
def jep_reference_role(role, rawtext, text, lineno, inliner, from docutils import nodes,utils
options={}, content=[]): from docutils.parsers.rst.roles import set_classes
'''Role to make handy references to Jabber Enhancement Proposals (JEP). except:
def create_xhtml(text):
return None
else:
def jep_reference_role(role, rawtext, text, lineno, inliner,
options={}, content=[]):
'''Role to make handy references to Jabber Enhancement Proposals (JEP).
Use as :JEP:`71` (or jep, or jep-reference). Use as :JEP:`71` (or jep, or jep-reference).
Modeled after the sample in docutils documentation. Modeled after the sample in docutils documentation.
''' '''
from docutils import nodes,utils
from docutils.parsers.rst.roles import set_classes
jep_base_url = 'http://www.jabber.org/jeps/' jep_base_url = 'http://www.jabber.org/jeps/'
jep_url = 'jep-%04d.html' jep_url = 'jep-%04d.html'
try: try:
jepnum = int(text) jepnum = int(text)
if jepnum <= 0: if jepnum <= 0:
raise ValueError raise ValueError
except ValueError: except ValueError:
msg = inliner.reporter.error( msg = inliner.reporter.error(
'JEP number must be a number greater than or equal to 1; ' 'JEP number must be a number greater than or equal to 1; '
'"%s" is invalid.' % text, line=lineno) '"%s" is invalid.' % text, line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg) prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg] return [prb], [msg]
ref = jep_base_url + jep_url % jepnum ref = jep_base_url + jep_url % jepnum
set_classes(options) set_classes(options)
node = nodes.reference(rawtext, 'JEP ' + utils.unescape(text), refuri=ref, node = nodes.reference(rawtext, 'JEP ' + utils.unescape(text), refuri=ref,
**options) **options)
return [node], [] return [node], []
roles.register_canonical_role('jep-reference', jep_reference_role) roles.register_canonical_role('jep-reference', jep_reference_role)
from docutils.parsers.rst.languages.en import roles from docutils.parsers.rst.languages.en import roles
roles['jep-reference'] = 'jep-reference' roles['jep-reference'] = 'jep-reference'
roles['jep'] = 'jep-reference' roles['jep'] = 'jep-reference'
class HTMLGenerator: class HTMLGenerator:
'''Really simple HTMLGenerator starting from publish_parts. '''Really simple HTMLGenerator starting from publish_parts.
It reuses the docutils.core.Publisher class, which means it is *not* It reuses the docutils.core.Publisher class, which means it is *not*
threadsafe. threadsafe.
''' '''
def __init__(self, def __init__(self,
settings_spec=None, settings_spec=None,
settings_overrides=dict(report_level=5, halt_level=5), settings_overrides=dict(report_level=5, halt_level=5),
config_section='general'): config_section='general'):
self.pub = Publisher(reader=None, parser=None, writer=None, self.pub = Publisher(reader=None, parser=None, writer=None,
settings=None, settings=None,
source_class=io.StringInput, source_class=io.StringInput,
destination_class=io.StringOutput) destination_class=io.StringOutput)
self.pub.set_components(reader_name='standalone', self.pub.set_components(reader_name='standalone',
parser_name='restructuredtext', parser_name='restructuredtext',
writer_name='html') writer_name='html')
#hack: JEP-0071 does not allow HTML char entities, so we hack our way out of it. # hack: JEP-0071 does not allow HTML char entities, so we hack our way
# &mdash; == u"\u2014" # out of it.
# a setting to only emit charater entities in the writer would be nice # &mdash; == u"\u2014"
# FIXME: several &nbsp; are emitted, and they are explicitly forbidden in the JEP # a setting to only emit charater entities in the writer would be nice
# &nbsp; == u"\u00a0" # FIXME: several &nbsp; are emitted, and they are explicitly forbidden
self.pub.writer.translator_class.attribution_formats['dash'] = (u'\u2014', '') # in the JEP
self.pub.process_programmatic_settings(settings_spec, # &nbsp; == u"\u00a0"
settings_overrides, self.pub.writer.translator_class.attribution_formats['dash'] = (
config_section) u'\u2014', '')
self.pub.process_programmatic_settings(settings_spec,
settings_overrides,
config_section)
def create_xhtml(self, text, def create_xhtml(self, text,
destination=None, destination=None,
destination_path=None, destination_path=None,
enable_exit_status=None): enable_exit_status=None):
''' Create xhtml for a fragment of IM dialog. ''' Create xhtml for a fragment of IM dialog.
We can use the source_name to store info about We can use the source_name to store info about
the message.''' the message.'''
self.pub.set_source(text, None) self.pub.set_source(text, None)
self.pub.set_destination(destination, destination_path) self.pub.set_destination(destination, destination_path)
output = self.pub.publish(enable_exit_status=enable_exit_status) output = self.pub.publish(enable_exit_status=enable_exit_status)
#kludge until we can get docutils to stop generating (rare) &nbsp; entities # kludge until we can get docutils to stop generating (rare) &nbsp;
return u'\u00a0'.join(self.pub.writer.parts['fragment'].strip().split('&nbsp;')) # entities
return u'\u00a0'.join(self.pub.writer.parts['fragment'].strip().split(
'&nbsp;'))
Generator = HTMLGenerator() Generator = HTMLGenerator()
def create_xhtml(text):
return Generator.create_xhtml(text)
def create_xhtml(text):
return Generator.create_xhtml(text)
if __name__ == '__main__': if __name__ == '__main__':
print Generator.create_xhtml(''' print Generator.create_xhtml('''