X-Chat-Skript, um [[solche links]] in xchat anklickbar zu machen:
die aktuelle Version findet man unter fr:Utilisateur:FoeNyx/wmlinksubber.py, siehe auch en:Wikipedia:Scripts
(ich selbst hatte nur wenig Anteil daran)

# filename: wmlinksubber.py

__module_name__ = "wmlinksubber" 
__module_version__ = "0.0.7" 
__module_description__ = "Replaces [[links like this]] with the appropriate URL"
__module_author__ = "[[Benutzer:Andre Riemann]], [[en:User:Jeronim]], [[fr:Utilisateur:FoeNyx]]"

debug = False

import re
import urllib
import xchat

def subwmlinks(word, word_eol, userdata):
        channel = xchat.get_info("channel")
        defaultURL = None
        isUTF8 = False
        try:
                defaultURL = freenodeChannelsToWikipediaURL[channel]
                if debug: print defaultURL
                if not defaultURL :
                        return xchat.EAT_NONE
        except:
                if debug: print "not a registered channel"
                return xchat.EAT_NONE

        event, pos = userdata
        nick=word[0]
        subbedchunks = []
        changed = False

        try:
                chunks = re_link.split(word[pos])
        except IndexError:
                return xchat.EAT_NONE
        for chunk in chunks:
                # if chunk is a [[something]]
                if re_link.match(chunk):                        
                        linktext = chunk[2:-2]
                        caption = ""
                        try:
                                for x in range(len(linktext)) :
                                        if linktext[x] == "|":
                                                caption = " " + linktext[x+1:]
                                                linktext = linktext[:x]                                         
                                                break
                        except:
                                pass
                        
                        linktext = linktext.replace(" ","_")
                        linktext = urllib.quote(linktext,":/|")

                        # lets test if it's an external wiki
                        matchobj = re_interOtherWikis.match(linktext,0)
                        if matchobj:
                                nameSpace = matchobj.group("namespace")
                                urlWiki = otherWikiNamespaces[nameSpace]
                                
                                subbedchunks.append('(' +
                                                    color + "8"
                                                    + re_interOtherWikis.sub(urlWiki, linktext)
                                                    + caption 
                                                    + reset_color + ')')
                                
                        else: 
                                # now lets test if it's an wikimedia projects interwiki
                                found = False
                                for reNS in wikimediaNamespaceMapOrder:
                                        if not found and reNS.match(linktext):
                                                subbedchunks.append('(' +
                                                                    color + "7"
                                                                    + reNS.sub(wikimediaNamespaceMap[reNS],linktext)
                                                                    + caption
                                                                    + reset_color + ')')
                                                found = True
                                                
                                # else we use the default channel mapping
                                if not found:
                                        subbedchunks.append('(' +
                                                            color + "9" + defaultURL +
                                                            linktext +
                                                            caption + 
                                                            reset_color + ')')
                        changed = True
                else:
                        subbedchunks.append(chunk)
                        
        if changed:
                xchat.emit_print(event, nick, "".join(subbedchunks))
                return xchat.EAT_XCHAT
        else:
                return xchat.EAT_NONE

re_link = re.compile(r'(\[\[[^\[\]]+\]\])')

freenodeChannelsToWikipediaNamespaces = {
        "#fr.wikipedia"   : {"namespace":"w:fr:",    "chan-encoding":"UTF-8"},
        "#wikipedia"      : {"namespace":"w:en:",     "chan-encoding":"ascii"},       
        "#de.wikipedia"   : {"namespace":"w:de:",    "chan-encoding":"latin-1"},
        "#is.wikipedia"   : {"namespace":"w:is",     "chan-encoding":"UTF-8"},
        "#ja.wikipedia"   : {"namespace":"w:ja:",    "chan-encoding":"ISO-2022-JP"},  
        "#frrc.wikipedia" : {"namespace":"w:fr:",    "chan-encoding":"UTF-8"},
        "#mediawiki"      : {"namespace":"w:test:",  "chan-encoding":"latin-1"},
        "#wikimedia"      : {"namespace":"m:",       "chan-encoding":"latin-1"},
        "#zwiki"          : {"namespace":"ZWiki:",   "chan-encoding":"latin-1"}       
        }
#chan encoding is not used yet

languagesList = ["aa","ab","af","ak","als","am","an","ar","arc","as","ast","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","cho","chr","chy","co","cr","cs","csb","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","haw","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lv","mg","mh","mi","minnan","minnan","mk","ml","mn","mo","mr","ms","mt","mus","my","na","nah","nb","nds","ne","ng","nl","nn","no","nv","ny","oc","om","or","pa","pi","pl","ps","pt","qu","rm","rn","ro","roa-rup","ru","rw","sa","sc","sd","se","sg","sh","sh","si","simple","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","test","tg","th","ti","tk","tl","tlh","tlh","tn","to","tokipona","tpi","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zh-cfr","zu"
]

#namespace pattern to url pattern
# (%s) is for lang list

# Try to substitute the longer pattern before the shorter or it will match the shorter first
wikimediaProjectsMapOrder = [
        '(w:(%s)):(.*)','(w):(.*)',
        '(m):(.*)',
        '(wiktionary:(%s)):(.*)','(wiktionary):(.*)',
        '(wikibooks:(%s)):(.*)','(wikibooks):(.*)',
        '(wikisource:(%s)):(.*)','(wikisource):(.*)',
        '(wikiquote:(%s)):(.*)','(wikiquote):(.*)',
        '(%s):(.*)'
        ]

# the last one is a tricky one for ppl who forget the w: before language (as in interwiki)
wikimediaProjectsMap = {
        '(w:(%s)):(.*)':'http://\\2.wikipedia.org/wiki/\\3',
        '(w):(.*)':'http://www.wikipedia.org/wiki/\\2',
        '(m):(.*)':'http://meta.wikimedia.org/wiki/\\2',
        '(wiktionary:(%s)):(.*)':'http://\\2.wiktionary.org/wiki/\\3',
        '(wiktionary):(.*)':'http://www.wiktionary.org/wiki/\\2',       
        '(wikibooks:(%s)):(.*)' :'http://\\2.wikibooks.org/wiki/\\3',
        '(wikibooks):(.*)' :'http://www.wikibooks.org/wiki/\\2',        
        '(wikisource:(%s)):(.*)':'http://\\2.wikisource.org/wiki/\\3',
        '(wikisource):(.*)':'http://www.wikisource.org/wiki/\\2',
        '(wikiquote:(%s)):(.*)' :'http://\\2.wiktionary.org/wiki/\\3',
        '(wikiquote):(.*)' :'http://www.wiktionary.org/wiki/\\2',
        '(%s):(.*)':'http://\\1.wikipedia.org/wiki/\\2'
        }

#the list of language pipe separated
patternLang = ""
first = True
for lang in languagesList:
        if first :
                first = False
        else:
                patternLang = patternLang + "|"
        patternLang = patternLang + lang

# The non mediawiki Wikies
otherWikiNamespaces = {
        'AbbeNormal':'http://www.ourpla.net/cgi-bin/pikie.cgi?\\2',
        'AcadWiki':'http://xarch.tu-graz.ac.at/autocad/wiki/\\2',
        'Acronym':'http://www.acronymfinder.com/af-query.asp?String=exact&Acronym=\\2',
        'Advogato':'http://www.advogato.org/\\2',
        'AIWiki':'http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?\\2',
        'ALife':'http://news.alife.org/wiki/index.php?\\2',
        'AndStuff':'http://andstuff.org/wiki.php?\\2',
        'Annotation':'http://bayle.stanford.edu/crit/nph-med.cgi/\\2',
        'AnnotationWiki':'http://www.seedwiki.com/page.cfm?wikiid=368&doc=\\2',
        'BEMI':'http://bemi.free.fr/vikio/index.php?\\2',
        'BenefitsWiki':'http://www.benefitslink.com/cgi-bin/wiki.cgi?\\2',
        'BridgesWiki':'http://c2.com/w2/bridges/\\2',
        'C2find':'http://c2.com/cgi/wiki?FindPage&value=\\2',
        'Cache':'http://www.google.com/search?q=cache:\\2',
        'CLiki':'http://ww.telent.net/cliki/\\2',
        'CmWiki':'http://www.ourpla.net/cgi-bin/wiki.pl?\\2',
        'CorpKnowPedia':'http://corpknowpedia.org/wiki/index.php/\\2',
        'CreationMatters':'http://www.ourpla.net/cgi-bin/wiki.pl?\\2',
        'DejaNews':'http://www.deja.com/=dnc/getdoc.xp?AN=\\2',
        'Dictionary':'http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=\\2',
        'Disinfopedia':'http://www.disinfopedia.org/wiki.phtml?title=\\2',
        'DiveIntoOsx':'http://diveintoosx.org/\\2',
        'DocBook':'http://docbook.org/wiki/moin.cgi/\\2',
        'DolphinWiki':'http://www.object-arts.com/wiki/html/Dolphin/\\2',
        'EcheI':'http://www.ikso.net/cgi-bin/wiki.pl?\\2',
        'EcxeI':'http://www.ikso.net/cgi-bin/wiki.pl?\\2',
        'EfnetCeeWiki':'http://purl.net/wiki/c/\\2',
        'EfnetCppWiki':'http://purl.net/wiki/cpp/\\2',
        'EfnetPythonWiki':'http://purl.net/wiki/python/\\2',
        'EfnetXmlWiki':'http://purl.net/wiki/xml/\\2',
        'EljWiki':'http://elj.sourceforge.net/phpwiki/index.php/\\2',
        'EmacsWiki':'http://www.emacswiki.org/cgi-bin/wiki.pl?\\2',
        'EnciclopediaLibre':'http://enciclopedia.us.es/index.php/\\2',
        'EoKulturCentro':'http://esperanto.toulouse.free.fr/wakka.php?wiki=\\2',
        'FinalEmpire':'http://final-empire.sourceforge.net/cgi-bin/wiki.pl?\\2',
        'FIRSTwiki':'http://firstwiki.org/index.php/\\2',
        'Foldoc':'http://www.foldoc.org/foldoc/foldoc.cgi?\\2',
        'FoxWiki':'http://fox.wikis.com/wc.dll?Wiki~\\2',
        'FreeBSDman':'http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=\\2',
        'GEJ':'http://www.esperanto.de/cgi-bin/aktivikio/wiki.pl?\\2',
        'Google':'http://www.google.com/search?q=\\2',
        'GoogleGroups':'http://groups.google.com/groups?q=\\2',
        'GotAMac':'http://www.got-a-mac.org/\\2',
        'GreenCheese':'http://www.greencheese.org/\\2',
        'HammondWiki':'http://www.dairiki.org/HammondWiki/index.php3?\\2',
        'Haribeau':'http://wiki.haribeau.de/cgi-bin/wiki.pl?\\2',
        'IAWiki':'http://www.IAwiki.net/\\2',
        'IMDB':'http://us.imdb.com/Title?\\2',
        'JargonFile':'http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=\\2',
        'JEFO':'http://www.esperanto-jeunes.org/vikio/index.php?\\2',
        'JiniWiki':'http://www.cdegroot.com/cgi-bin/jini?\\2',
        'JspWiki':'http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=\\2',
        'KmWiki':'http://www.voght.com/cgi-bin/pywiki?\\2',
        'KnowHow':'http://www2.iro.umontreal.ca/~paquetse/cgi-bin/wiki.cgi?\\2',
        'LanifexWiki':'http://opt.lanifex.com/cgi-bin/wiki.pl?\\2',
        'LinuxWiki':'http://www.linuxwiki.de/\\2',
        'LinuxFr:Utilisateur':'http://linuxfr.org/~\\2',
        'Lojban':'http://www.lojban.org/tiki/tiki-index.php?page=\\2',
        'LugKR':'http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?\\2',
        'MathSongsWiki':'http://SeedWiki.com/page.cfm?wikiid=237&doc=\\2',
        'MbTest':'http://www.usemod.com/cgi-bin/mbtest.pl?\\2',
        'MeatBall':'http://www.usemod.com/cgi-bin/mb.pl?\\2',
        'MemoryAlpha':'http://www.memory-alpha.org/en/index.php/?\\2',
        'Metaweb':'http://www.metaweb.com/wiki/wiki.phtml?title=\\2',
        'MetaWiki':'http://sunir.org/apps/meta.pl?\\2',
        'MetaWikiPedia':'http://meta.wikipedia.org/wiki/\\2',
        'MoinMoin':'http://purl.net/wiki/moin/\\2',
        'MuWeb':'http://www.dunstable.com/scripts/MuWebWeb?\\2',
        'NetVillage':'http://www.netbros.com/?\\2',
        'OpenWiki':'http://openwiki.com/?\\2',
        'OrgPatterns':'http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?\\2',
        'PangalacticOrg':'http://www.pangalactic.org/Wiki/\\2',
        'PersonalTelco':'http://www.personaltelco.net/index.cgi/\\2',
        'PhpWiki':'http://phpwiki.sourceforge.net/phpwiki/index.php?\\2',
        'Pikie':'http://pikie.darktech.org/cgi/pikie?\\2',
        'PMEG':'http://www.bertilow.com/pmeg/\\2.php',
        'PPR':'http://c2.com/cgi/wiki?\\2',
        'PurlNet':'http://purl.oclc.org/NET/\\2',
        'PythonInfo':'http://www.python.org/cgi-bin/moinmoin/\\2',
        'PythonWiki':'http://www.pythonwiki.de/\\2',
        'PyWiki':'http://www.voght.com/cgi-bin/pywiki?\\2',
        'ReVo':'http://purl.org/NET/voko/revo/art/\\2.html',
        'RFC':'http://www.rfc-editor.org/rfc/rfc\\2.txt',
        'Slashdot':'http://slashdot.org/search.pl?query=\\2',
        'Slashdot:User':'http://slashdot.org/~\\2',     
        'SeaPig':'http://www.seapig.org/ \\2',
        'SeattleWireless':'http://seattlewireless.net/?\\2',
        'SenseisLibrary':'http://senseis.xmp.net/?\\2',
        'Shakti':'http://cgi.algonet.se/htbin/cgiwrap/pgd/ShaktiWiki/\\2',
        'SourceForge':'http://sourceforge.net/\\2',
        'Squeak':'http://minnow.cc.gatech.edu/squeak/\\2',
        'StrikiWiki':'http://ch.twi.tudelft.nl/~mostert/striki/teststriki.pl?\\2',
        'Susning':'http://www.susning.nu/\\2',
        'SVGWiki':'http://www.protocol7.com/svg-wiki/default.asp?\\2',
        'Tavi':'http://tavi.sourceforge.net/index.php?\\2',
        'TEJO':'http://www.tejo.org/vikio/\\2',
        'TmNet':'http://www.technomanifestos.net/?\\2',
        'TMwiki':'http://www.EasyTopicMaps.com/?page=\\2',
        'Turismo':'http://www.tejo.org/turismo/\\2',
        'TWiki':'http://twiki.org/cgi-bin/view/\\2',
        'TwistedWiki':'http://purl.net/wiki/twisted/\\2',
        'UEA':'http://www.tejo.org/uea/\\2',
        'Unreal':'http://wiki.beyondunreal.com/wiki/\\2',
        'USEJ':'http://www.tejo.org/usej/\\2',
        'UseMod':'http://www.usemod.com/cgi-bin/wiki.pl?\\2',
        'VisualWorks':'http://wiki.cs.uiuc.edu/VisualWorks/\\2',
        'WebDevWikiNL':'http://www.promo-it.nl/WebDevWiki/index.php?page=\\2',
        'WebSeitzWiki':'http://webseitz.fluxent.com/wiki/\\2',
        'Why':'http://clublet.com/c/c/why?\\2',
        'Wiki':'http://c2.com/cgi/wiki?\\2',
        'Wikibooks':'http://wikibooks.org/wiki/\\2',
        'Wikinfo':'http://www.wikinfo.org/wiki.php?title=\\2',
        'Wikipedia':'http://www.wikipedia.org/wiki/\\2',
        'Wikiquote':'http://wikiquote.org/wiki/\\2',
        'Wikisource':'http://sources.wikipedia.org/wiki/\\2',
        'WikiTravel':'http://wikitravel.org/en/article/\\2',
        'WikiWorld':'http://WikiWorld.com/wiki/index.php/\\2',
        'Wiktionary':'http://wiktionary.org/wiki/\\2',
        'YpsiEyeball':'http://sknkwrks.dyndns.org:1957/writewiki/wiki.pl?\\2',
        'ZWiki':'http://www.zwiki.org/\\2'
}

# build otherWiki regexp pattern
re_interOtherWikis = ""
pattern = "%s|%s"
for wiki in otherWikiNamespaces.keys():
        re_interOtherWikis = pattern % (re_interOtherWikis, wiki)
pattern = "(?P<namespace>%s):(?P<text>.*)" % re_interOtherWikis[1:]
if debug : print "re_interOtherWikis :", pattern
re_interOtherWikis = re.compile(pattern)

#the build regexp obj to url pattern
wikimediaNamespaceMapOrder = []
wikimediaNamespaceMap = {}      
for pattern in wikimediaProjectsMapOrder:
        url = wikimediaProjectsMap[pattern]
        try:
                pattern = pattern % patternLang
        except:
                pass
        if debug : print pattern
        re_interWikis = re.compile(pattern)
        wikimediaNamespaceMapOrder.append(re_interWikis)
        wikimediaNamespaceMap[re_interWikis] = url

# build channel to url map according to wikimediaProjectsMap and otherWikiNamespaces
freenodeChannelsToWikipediaURL = {}

def buildChannelToURL(chan="",chanNS=""):
        # check in mediawiki namespaces
        for reNS in wikimediaNamespaceMapOrder:
                if reNS.match(chanNS):
                        freenodeChannelsToWikipediaURL[chan] = reNS.sub(wikimediaNamespaceMap[reNS],chanNS)
                        if debug : print chan, freenodeChannelsToWikipediaURL[chan]
                        return True

        # check in other wiki namespace
        matchobj = re_interOtherWikis.match(chanNS)
        if matchobj:
                nameSpace = matchobj.group("namespace")
                urlWiki = otherWikiNamespaces[nameSpace]                                
                freenodeChannelsToWikipediaURL[chan] = re_interOtherWikis.sub(urlWiki, chanNS)
        else:
                return False
        return True

for chan in freenodeChannelsToWikipediaNamespaces.keys():
        chanNS = freenodeChannelsToWikipediaNamespaces[chan]["namespace"]
        buildChannelToURL(chan, chanNS)
        
if debug : print freenodeChannelsToWikipediaURL

def changeNamespace(word, word_eol, userdata): 
        channel = xchat.get_info("channel")
        #print channel
        if len(word) < 2:            
                if channel in freenodeChannelsToWikipediaNamespaces.keys():
                        print ("Current default namespace for %s channel is %s" %
                               (channel, freenodeChannelsToWikipediaNamespaces[channel]["namespace"] ))
                else: 
                        print "No current wiki namespace enabled for this channel"
        else:
                namespace = word_eol[1]
                #print namespace
                if namespace == "None":
                        del freenodeChannelsToWikipediaNamespaces[channel]
                        del freenodeChannelsToWikipediaURL[channel]
                        print "Default namespace for %s channel have been removed" % channel
                else:
                        freenodeChannelsToWikipediaNamespaces[channel] = {"namespace":namespace, "chan-encoding":"latin-1"}
                        if buildChannelToURL(channel,namespace) :
                                print "Default namespace for %s channel have been set to %s" % (channel, namespace)
                        else:
                                print "No namespaces matching (see /LISTWNS, it's case sensitive and dont forget the trailing ':')"
                                
        return xchat.EAT_ALL

def listAvailableNameSpace(word, word_eol, userdata):
        print "*** Available wiki namespaces ***",
        print "\n**** External wikis namespaces ****"
        for namespace in otherWikiNamespaces.keys():
                print namespace,
        print "\n**** Mediawiki namespaces ****"
        for namespace in wikimediaProjectsMap.keys():
                print namespace.replace("):(.*)","").replace('(','').replace(")","") + ":",
        print "\nwhere %s can be one of the language among :"
        for language in languagesList:
                print language,
        print #flush the buffer
        return xchat.EAT_ALL

def listEnabledNameSpaces(word, word_eol, userdata):
        print "*** Enabled wiki namespaces ***"
        print "channel".ljust(30), "namespace".ljust(30)
        for channel in freenodeChannelsToWikipediaNamespaces.keys():
                namespace = freenodeChannelsToWikipediaNamespaces[channel]["namespace"]
                print channel.ljust(30), namespace.ljust(30)
        return xchat.EAT_ALL
                
xchat.hook_command("DEFAULTWNS", changeNamespace,
                   help="/DEFAULTWNS [<namespace>] Print or Change the default wiki namespace for this channel. If <namespace> value is 'None' then the current mapping will be removed.") 
xchat.hook_command("LISTWNS", listAvailableNameSpace,
                   help="/LISTWNS List the available wiki namespaces") 
xchat.hook_command("MAPWNS", listEnabledNameSpaces,
                   help="/MAPWNS Show the current mapping of channels and wiki namespaces")

print "Plugin %s Commands : %s" %( __module_name__, "DEFAULTWNS LISTWNS MAPWNS" )

EVENTS = []
EVENTS.append(("Channel Message", 1))
EVENTS.append(("Channel Msg Hilight", 1))
# if you don't want it to replace text which ''you'' type, comment the following out ( with"#" like this line)
EVENTS.append(("Your Message", 1))
EVENTS.append(("Private Message", 1))
EVENTS.append(("Private Message to Dialog", 1))

for event in EVENTS:
        xchat.hook_print(event[0], subwmlinks, event)

reset_color ='\017'
color = '\003'
#'\0037' would be orange -> color + '7' for mediawiki
#'\0038' would be yellow -> color + '8' for otherwiki
#'\0038' would be green  -> color + '9' for localwiki

def unload(userdata):
        print "Plugin " + __module_name__ + " " + __module_version__ + " unloaded."
xchat.hook_unload(unload)

print "Plugin " + __module_name__ + " " + __module_version__ + " loaded."

#ChangeLog:

# 2004-08-01, v0.0.7 (Foenyx)
# Show the piped label in [[Reference|label]]

# 2004-07-30, v0.0.6 (Foenyx)
# added per channel default wiki namespace selection,
# other wiki (non mediawiki) intermap
# and an url encode for the non ascii text
# some commands to manage mapping of current channel with namespace
# a channel need to have a default namespace to urlize the [[expr]]
# and a lot of obfuscated code :( sorry 

# 2004-06-09, v0.0.5
# added color support to point out which link was substituted
# regexp upgraded to prevent links with [ or ] inside, e.g. [[[Test]]
# brackets around the link because a link with leading [ don't acts as link

# 2003-03-29, v0.0.4
# bugfix for when pasting text with consecutive line-breaks
# the [[quick]] [[brown]] [[w:fox]] jumps
# over the [[lazy]] [[wiktionary:dog]]