# -*- coding: iso-8859-1 -*-
"""
MoinMoin - GNOME theme
Based on rightsidebar theme,
Created by and for crw.
Later it was rewritten by Nir Soffer for MoinMoin release 1.3.
Copyright: 2005 by Nir Soffer
Later is was rewritten for GNOME layout by Frederic Peters.
@copyright: 2005 by Nir Soffer, 2007 by Frederic Peters, 2013 by William Jon McCann
@license: GNU GPL, see COPYING for details.
"""
from MoinMoin.theme import ThemeBase
from MoinMoin.parser.text_moin_wiki import Parser
from MoinMoin import macro
from MoinMoin import i18n, wikiutil, config, version
from MoinMoin.Page import Page
import sys, re, cStringIO
class Theme(ThemeBase):
name = 'gnome'
def __init__(self, request):
ThemeBase.__init__(self, request)
_ = self.request.getText
_ = lambda x: x
self.icons['diffrc'] = (_('Diffs'), 'gnome-moin-diff.png', 16, 16)
self.icons.update({
'attach': ('%(attach_count)s', 'mail-attachment-symbolic.png', 16, 16),
'bottom': (_('[BOTTOM]'), 'go-bottom-symbolic.png', 16, 16),
'deleted': (_('[DELETED]'), 'edit-delete-symbolic.png', 16, 16),
'diff': (_('Diffs'), 'gnome-moin-diff.png', 16, 16),
'diffrc': (_('[DIFF]'), 'gnome-moin-diff.png', 16, 16),
'edit': (_('Edit'), 'text-editor-symbolic.png', 16, 16),
'find': ('%(page_find_page)s', 'edit-find-symbolic.png', 16, 16),
'help': ('%(page_help_contents)s', 'help-browser-symbolic.png', 16, 16),
'home': (_('Home'), 'go-home-symbolic.png', 16, 16),
'interwiki': ('[%(wikitag)s]', 'send-to-symbolic.png', 16, 16),
'new': (_('[NEW]'), 'gnome-moin-new.png', 16, 16),
'print': (_('Print'), 'printer-symbolic.png', 16, 16),
'rss': (_('[RSS]'), 'gnome-moin-rss.png', 16, 16),
'searchbutton': ('[?]', 'edit-find-symbolic.png', 16, 16),
'top': (_('[TOP]'), 'go-top-symbolic.png', 16, 16),
'updated': (_('[UPDATED]'), 'view-refresh-symbolic.png', 16, 16),
'www': ('[WWW]', 'web-browser-symbolic.png', 16, 16),
'/!\\': ("/!\\", 'dialog-warning-symbolic.png', 16, 16),
'(!)': ("(!)", 'dialog-information-symbolic.png', 16, 16),
'': ("", 'dialog-question-symbolic.png', 16, 16),
'(./)': ("(./)", 'object-select-symbolic.png', 16, 16)
})
# Squash the "fancy links" abomination. This is to some extent
# a work-around for a Moin-1.3.5 bug where the user preference
# doesn't work, but I don't want people to *ever* see them.
def make_icon(self, icon, vars=None):
if icon == 'www' or icon == 'mailto':
return ''
else:
return ThemeBase.make_icon(self, icon, vars)
def startPage(self):
""" Start page div with page language and direction
@rtype: unicode
@return: page div with language and direction attribtues
"""
if self.request.form.get('action', [''])[0] == 'edit':
startpage = u'
\n' % self.content_lang_attr()
else:
startpage = u'
\n' % self.content_lang_attr()
return startpage
def splitNavilink(self, text, localize=1):
pagename, link = ThemeBase.splitNavilink(self, text, localize = localize)
return (pagename, re.sub(r'(
)(.*)()', r'\1\2\3', link))
def tabs(self, d, skip_current=False):
### based on ThemeBase.navibar
request = self.request
found = {} # pages we found. prevent duplicates
items = [] # navibar items
item = u'%s'
current = d['page_name']
if skip_current:
found[current] = 1
# Process config navi_bar
if request.cfg.navi_bar:
for text in request.cfg.navi_bar:
pagename, link = self.splitNavilink(text)
if pagename in found:
continue
if pagename == current:
cls = 'wikilink selected'
else:
cls = 'wikilink'
items.append(item % (cls, link))
found[pagename] = 1
# Add user links to wiki links, eliminating duplicates.
userlinks = request.user.getQuickLinks()
for text in userlinks:
# Split text without localization, user knows what he wants
pagename, link = self.splitNavilink(text, localize=0)
if not pagename in found:
continue
if pagename == current:
cls = 'userlink selected'
else:
cls = 'userlink'
items.append(item % (cls, link))
found[pagename] = 1
# Assemble html
html = u''.join(items)
return html
def title_with_separators2(self, d):
""" Assemble the title using slashes, not
@param d: parameter dictionary
@rtype: string
@return: title html
"""
_ = self.request.getText
if d['title_text'] == d['page'].split_title():
# just showing a page, no action
segments = d['page_name'].split('/')
link_text = segments[-1]
link = d['page'].link_to(self.request, link_text)
if len(segments) <= 1:
html = link
else:
content = []
curpage = ''
for s in segments[:-1]:
curpage += s
content.append(Page(self.request,
curpage).link_to(self.request, s))
curpage += '/'
path_html = u'/'.join(content)
html = u'%s/%s' % (path_html, link)
else:
html = wikiutil.escape(d['title_text'])
return u'%s' % html
def header(self, d):
"""
Assemble page header
@param d: parameter dictionary
@rtype: string
@return: page header html
"""
_ = self.request.getText
html_title = self.title_with_separators2(d)
html_tabs = self.tabs(d, skip_current=True)
html = [
u'''
''',
self.msg(d),
# Page
self.startPage(),
]
return u'\n'.join(html)
def editorheader(self, d):
_ = self.request.getText
title = _('Edit "%(pagename)s"') % {'pagename': d['page'].split_title(self.request)}
return u'\n'.join([self.header(d),
u'
%s
' % title])
def footer_editbar(self, d):
# Only show an editbar for logged-in users
if (self.request.user.valid):
html = [
u''
]
return u'\n'.join(html)
else:
return u''
def footer(self, d, **keywords):
""" Assemble wiki footer
@param d: parameter dictionary
@keyword ...:...
@rtype: unicode
@return: page footer html
"""
page = d['page']
html = [
# End of page
self.pageinfo(page),
self.endPage(),
# Post footer custom html
#self.emit_custom_html(self.cfg.page_footer2),
u'''
'''
]
return u'\n'.join(html)
def execute(request):
""" Generate and return a theme object
@param request: the request object
@rtype: MoinTheme
@return: Theme object
"""
return Theme(request)
class IncludeParser:
def __init__(self, request, page):
self.parser = Parser("", request)
# Format the empty string, making it set its internal data (ugh!).
out = cStringIO.StringIO()
backup = sys.stdout, request.write
sys.stdout, request.write = out, out.write
self.parser.format(page.formatter)
sys.stdout, request.write = backup
self.include_re = re.compile("\[\[Include(?:\(.*?\))?\]\]")
self.macro = macro.Macro(self.parser)
# This is really deep and cool black magic. Basically, it creates
# a local copy of the function macro.Include.execute that behaves
# exactly like the original one, but with a different "Page"
# global. This allows us to follow changes in the Include macro
# without much trouble.
from MoinMoin.macro.Include import execute
func_globals = {}
func_globals.update(execute.func_globals)
class IncludePage(Page):
incparser = self
def send_page(self, request, msg=None, **keywords):
request.write(self.incparser._parse(self.get_raw_body()))
func_globals["Page"] = IncludePage
self.execute = new.function(execute.func_code, func_globals,
execute.func_name,
execute.func_defaults)