# GNU Solfege - eartraining for GNOME
# Copyright (C) 2000, 2001, 2002  Tom Cato Amundsen
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

import gtk
import GDK
import re, string

class GtkXmHTML(gtk.GtkScrolledWindow):
    def __init__(self):
        gtk.GtkScrolledWindow.__init__(self)
        self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.g_text = gtk.GtkText()
        self.g_text.set_word_wrap(gtk.TRUE)
        self.add(self.g_text)
        self.g_text.show()
        self.g_text.connect('event', self.on_event)
        self.g_text.set_editable(gtk.FALSE)
    def on_event(self, widget, event):
        if event.type == GDK.BUTTON_RELEASE and event.button == 3:
            href = self.get_href(self.g_text.get_position())
            if href:
              self.activate_cb(href)
    def get_href(self, idx):
        while idx > 0 and self.g_text.get_chars(idx, idx+1) not in  ["[", "]"]:
            idx = idx - 1
        if self.g_text.get_chars(idx, idx + 1) == ']':
            return
        r = re.compile("\[(.*?)\]")
        m = r.match(self.g_text.get_chars(idx, -1))
        return m.group(1)
    def source(self, txt):
        txt = self.html2text(txt)
        if self.g_text.get_length() > 0:
            self.g_text.delete_text(0, self.g_text.get_length())
        self.g_text.insert_defaults(txt)
    def html2text(self, html):
        # ugly, but simple
        if re.match("<html><body>\s*<pre>.*?GNU GENERAL PUBLIC LICENSE", html, re.MULTILINE|re.DOTALL):
            m = re.match("<html><body>\s*<pre>(.*?)</pre>\s*</body></html>", html, re.MULTILINE|re.DOTALL)
            if m:
                return m.group(1)
        whitespace_re = re.compile(r"(?s)(\s)")
        comment_re = re.compile(r"(?s)<!--.*?-->")
        html_re = re.compile(r"<.*?>")
        href_re = re.compile(r"""(?s)<a\s*href\s*=\s*"(.*?)"\s*>(.*?)</a>""")
        hx_re = re.compile(r"<h(\d)>(.*?)</h\1>")
        title_re = re.compile("<title>.*?</title>", re.DOTALL)
        html = comment_re.sub("", html)
        while 1:
            m = href_re.search(html)
            if not m:
                break
            html = html[:m.start()] + "%s[%s]" % (m.group(2), m.group(1)) + html[m.end():]
        while 1:
            m = hx_re.search(html)
            if not m:
                break
            html = html[:m.start()] \
                   + "{br}{br}%s{br}" % m.group(2) \
                   + "=" * len(m.group(2)) \
                   + "{br}" + html[m.end():]
        for old, new in (("<p>", "{p}"), ("<li>", "{li}"),
                         ("<hr>", "{hr}"), ("<br>", "{br}")):
            html = string.replace(html, old, new)
        html = title_re.sub("", html)
        html = html_re.sub("", html)
        html = whitespace_re.sub(" ", html)
        for old, new in (("{p}", "\n\n"), ("{li}", "\n\n * "),
                         ("{hr}", "-"*60), ("{br}", "\n")):
            html = string.replace(html, old, new)
        for old, new in (("&lt;", "<"), ("&gt;", ">")):
            html = string.replace(html, old, new)
        return html

