"""
    MoinMoin - LinkedFrom Macro     

    Modified from the OrphanedPages Macro by Jürgen Hermann
    and the PartialInclude Macro written by Seth Shikora.
    by Charles Crichton, Oxford University Computing Laboratory (2003)
    Charles.Crichton (in the domain of) comlab.ox.ac.uk

    I must say thanks to all those who have contributed to the MoinMoin markets - keep up the good work.
    
    Copyright (c) 2001 by Jürgen Hermann <jh@web.de>
    All rights reserved, see COPYING for details.
     
    Usage: [[LinkedFrom]] - List all the pages that statically link to the current page.
           [[LinkedFrom(regexp)]] - Only lists the linking pages that match the regular expression.

    Use this macro to show a list of all those pages that are linking to the current page. Optionally
    this list can be restricted to those pages that match a particular regular expression.
    
    I use it to keep a list of topic pages - such as ["Topic: UML"].
    Each of these topics contains a [[LinkedFrom]] macro.
    
    I then have a page for each paper which I have read. If the paper covers a particular topic I place
    a link to the topic on the page related to the paper. ["Topic: UML"] for example. The page then shows
    up automatically on the topic page.

"""

# Imports
from MoinMoin import config, user, wikiutil
from MoinMoin.Page import Page
from MoinMoin.i18n import _

import sys, cStringIO, re

_guard = 0


def execute(macro, args):

    if not args:
        pagename_re = re.compile(".*")
    else:
        try:
            pagename_re = re.compile(args)
        except re.error, e:
            return '<p><strong class="error">%s</strong></p>' % _('Error in regular expression.')
    
    # prevent recursive calls
    global _guard
    if _guard: return ''

    _guard = 1
    
    pages = wikiutil.getPageList(config.text_dir)
    pagelist = filter(pagename_re.search, pages)

    linkedfrom = {}
    
    this_page = macro.formatter.page

    for other_page_name in pagelist:
        other_page = Page(other_page_name)
        if other_page != this_page:
            links = other_page.getPageLinks(macro.request)
            for link in links:
                if link == this_page.page_name:
                    linkedfrom[other_page.page_name] = other_page.page_name
    _guard = 0

    # check for the extreme case
    if not linkedfrom:
        return "" #"<p><b>%s</b></p>" % _("No other pages link to this page in this wiki.")

    # return a list of page links
    linkedfromnames = linkedfrom.keys()
    linkedfromnames.sort()
    result = macro.formatter.bullet_list(1)
    for name in linkedfromnames:
        if not name: continue
        result = result + macro.formatter.listitem(1)
        result = result + macro.formatter.pagelink(name, generated=1)
        result = result + macro.formatter.listitem(0)
    result = result + macro.formatter.bullet_list(0)

    return result