From 9f766f81e3d304e175b0fc0f5c091128f024cbfa Mon Sep 17 00:00:00 2001 From: Antoine Durand-Gasselin Date: Mon, 10 Nov 2008 17:09:22 +0100 Subject: [PATCH] =?UTF-8?q?[wiki-lenny/local/macro]=20d'autres=20macros=20?= =?UTF-8?q?qui=20passaient=20=C3=A0=20la=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit darcs-hash:20081110160922-bd074-0b8f0a7ffd4e53456642c93b1c0017cbe5c9f682.gz --- wiki-lenny/local/macro/RandomIncludeQuote.py | 244 +++++++++++++++++++ wiki-lenny/local/macro/RandomPageInclude.py | 219 +++++++++++++++++ wiki-lenny/local/macro/RandomQuoteNum.py | 57 +++++ wiki-lenny/local/macro/SubscribeTo.py | 157 ++++++++++++ wiki-lenny/local/macro/TableOfContents.py | 186 ++++++++++++++ wiki-lenny/local/macro/TerminalSsh.py | 53 ++++ 6 files changed, 916 insertions(+) create mode 100644 wiki-lenny/local/macro/RandomIncludeQuote.py create mode 100644 wiki-lenny/local/macro/RandomPageInclude.py create mode 100644 wiki-lenny/local/macro/RandomQuoteNum.py create mode 100644 wiki-lenny/local/macro/SubscribeTo.py create mode 100644 wiki-lenny/local/macro/TableOfContents.py create mode 100644 wiki-lenny/local/macro/TerminalSsh.py diff --git a/wiki-lenny/local/macro/RandomIncludeQuote.py b/wiki-lenny/local/macro/RandomIncludeQuote.py new file mode 100644 index 00000000..78efccb2 --- /dev/null +++ b/wiki-lenny/local/macro/RandomIncludeQuote.py @@ -0,0 +1,244 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - RandomIncludeQuote macro + + This macro includes the formatted content of the given page(s). See + + http://purl.net/wiki/moinmaster/HelpOnMacros/Include + + for detailed docs. + + @copyright: 2000-2004 by Jürgen Hermann + @copyright: 2000-2001 by Richard Jones + @license: GNU GPL, see COPYING for details. +""" + +#Dependencies = ["pages"] # included page +Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks + +import re, StringIO +from MoinMoin import wikiutil +from MoinMoin.Page import Page +from MoinMoin.util import web + +_sysmsg = '

%s

' + +## keep in sync with TableOfContents macro! +_arg_heading = r'(?P,)\s*(|(?P[\'"])(?P.+?)(?P=hquote))' +_arg_level = r',\s*(?P\d*)' +_arg_from = r'(,\s*from=(?P[\'"])(?P.+?)(?P=fquote))?' +_arg_to = r'(,\s*to=(?P[\'"])(?P.+?)(?P=tquote))?' +_arg_sort = r'(,\s*sort=(?P(ascending|descending)))?' +_arg_items = r'(,\s*items=(?P\d+))?' +_arg_skipitems = r'(,\s*skipitems=(?P\d+))?' +_arg_titlesonly = r'(,\s*(?Ptitlesonly))?' +_arg_editlink = r'(,\s*(?Peditlink))?' +_args_re_pattern = r'^(?P[^,]+)(%s(%s)?%s%s%s%s%s%s%s)?$' % ( + _arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items, + _arg_skipitems, _arg_titlesonly, _arg_editlink) + +_title_re = r"^(?P\s*(?P=+)\s.*\s(?P=hmarker))$" + +def extract_titles(body, title_re): + titles = [] + for title, _ in title_re.findall(body): + h = title.strip() + level = 1 + while h[level:level+1] == '=': level = level+1 + depth = min(5,level) + title_text = h[level:-level].strip() + titles.append((title_text, level)) + return titles + +def execute(macro, text, args_re=re.compile(_args_re_pattern), title_re=re.compile(_title_re, re.M), called_by_toc=0): + request = macro.request + _ = request.getText + + # return immediately if getting links for the current page + if request.mode_getpagelinks: + return '' + + # parse and check arguments + args = args_re.match(text) + if not args: + return (_sysmsg % ('error', _('Invalid include arguments "%s"!')) % (text,)) + + # prepare including page + result = [] + print_mode = macro.form.has_key('action') and macro.form['action'][0] == "print" + this_page = macro.formatter.page + if not hasattr(this_page, '_macroInclude_pagelist'): + this_page._macroInclude_pagelist = {} + + # get list of pages to include + inc_name = wikiutil.AbsPageName(request, this_page.page_name, args.group('name')) + pagelist = [inc_name] + if inc_name.startswith("^"): + try: + inc_match = re.compile(inc_name) + except re.error: + pass # treat as plain page name + else: + # Get user filtered readable page list + pagelist = request.rootpage.getPageList(filter=inc_match.match) + + # sort and limit page list + pagelist.sort() + sort_dir = args.group('sort') + if sort_dir == 'descending': + pagelist.reverse() + max_items = args.group('items') + if max_items: + pagelist = pagelist[:int(max_items)] + + skipitems = 0 + if args.group("skipitems"): + skipitems = int(args.group("skipitems")) + titlesonly = args.group('titlesonly') + editlink = args.group('editlink') + + # iterate over pages + for inc_name in pagelist: + if not request.user.may.read(inc_name): + continue + if this_page._macroInclude_pagelist.has_key(inc_name): + result.append(u'

Recursive include of "%s" forbidden

' % (inc_name,)) + continue + if skipitems: + skipitems -= 1 + continue + fmt = macro.formatter.__class__(request, is_included=True) + fmt._base_depth = macro.formatter._base_depth + inc_page = Page(request, inc_name, formatter=fmt) + inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist + + # check for "from" and "to" arguments (allowing partial includes) + body = inc_page.get_raw_body() + '\n' + from_pos = 0 + to_pos = -1 + from_re = args.group('from') + if from_re: + try: + from_match = re.compile(from_re, re.M).search(body) + except re.error, e: + ##result.append("*** fe=%s ***" % e) + from_match = re.compile(re.escape(from_re), re.M).search(body) + if from_match: + from_pos = from_match.end() + else: + result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re) + to_re = args.group('to') + if to_re: + try: + to_match = re.compile(to_re, re.M).search(body, from_pos) + except re.error: + to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos) + if to_match: + to_pos = to_match.start() + else: + result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re) + + if titlesonly: + newbody = [] + levelstack = [] + for title, level in extract_titles(body[from_pos:to_pos], title_re): + if levelstack: + if level > levelstack[-1]: + result.append(macro.formatter.bullet_list(1)) + levelstack.append(level) + else: + while levelstack and level < levelstack[-1]: + result.append(macro.formatter.bullet_list(0)) + levelstack.pop() + if not levelstack or level != levelstack[-1]: + result.append(macro.formatter.bullet_list(1)) + levelstack.append(level) + else: + result.append(macro.formatter.bullet_list(1)) + levelstack.append(level) + result.append(macro.formatter.listitem(1)) + result.append(inc_page.link_to(request, title)) + result.append(macro.formatter.listitem(0)) + while levelstack: + result.append(macro.formatter.bullet_list(0)) + levelstack.pop() + continue + + if from_pos or to_pos != -1: + inc_page.set_raw_body(body[from_pos:to_pos], modified=True) + ##result.append("*** f=%s t=%s ***" % (from_re, to_re)) + ##result.append("*** f=%d t=%d ***" % (from_pos, to_pos)) + + if called_by_toc: + result.append(inc_page.get_raw_body()) + continue + + if not hasattr(request, "_Include_backto"): + request._Include_backto = this_page.page_name + + # do headings + level = None + if args.group('heading') and args.group('hquote'): + heading = args.group('htext') or inc_page.split_title(request) + level = 1 + if args.group('level'): + level = int(args.group('level')) + if print_mode: + result.append(macro.formatter.heading(1, level) + + macro.formatter.text(heading) + + macro.formatter.heading(0, level)) + else: + import sha + from MoinMoin import config + # this heading id might produce duplicate ids, + # if the same page is included multiple times + # Encode stuf we feed into sha module. + pntt = (inc_name + heading).encode(config.charset) + hid = "head-" + sha.new(pntt).hexdigest() + request._page_headings.setdefault(pntt, 0) + request._page_headings[pntt] += 1 + if request._page_headings[pntt] > 1: + hid += '-%d'%(request._page_headings[pntt],) + result.append( + #macro.formatter.heading(1, level, hid, + # icons=edit_icon.replace(' 1: + this_page._macroInclude_pagelist[inc_name] = \ + this_page._macroInclude_pagelist[inc_name] - 1 + else: + del this_page._macroInclude_pagelist[inc_name] + + # if no heading and not in print mode, then output a helper link + if editlink and not (level or print_mode): + result.extend([ + '', + ]) + # XXX page.link_to is wrong now, it escapes the edit_icon html as it escapes normal text + + # return include text + return ''.join(result) + +# vim:ts=4:sw=4:et diff --git a/wiki-lenny/local/macro/RandomPageInclude.py b/wiki-lenny/local/macro/RandomPageInclude.py new file mode 100644 index 00000000..dc4844fb --- /dev/null +++ b/wiki-lenny/local/macro/RandomPageInclude.py @@ -0,0 +1,219 @@ +# -*- coding: iso-8859-1 -*- +#Dependencies = ["pages"] # included page +Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks + +import re, StringIO +from MoinMoin import wikiutil, search +from MoinMoin.Page import Page +from MoinMoin.util import web +from random import choice + +_sysmsg = '

%s

' + +## keep in sync with TableOfContents macro! +_arg_heading = r'(?P,)\s*(|(?P[\'"])(?P.+?)(?P=hquote))' +_arg_level = r',\s*(?P\d*)' +_arg_from = r'(,\s*from=(?P[\'"])(?P.+?)(?P=fquote))?' +_arg_to = r'(,\s*to=(?P[\'"])(?P.+?)(?P=tquote))?' +_arg_sort = r'(,\s*sort=(?P(ascending|descending)))?' +_arg_items = r'(,\s*items=(?P\d+))?' +_arg_skipitems = r'(,\s*skipitems=(?P\d+))?' +_arg_titlesonly = r'(,\s*(?Ptitlesonly))?' +_arg_editlink = r'(,\s*(?Peditlink))?' +_args_re_pattern = r'^(?P[^,]+)(%s(%s)?%s%s%s%s%s%s%s)?$' % ( + _arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items, + _arg_skipitems, _arg_titlesonly, _arg_editlink) + +_title_re = r"^(?P\s*(?P=+)\s.*\s(?P=hmarker))$" + +def extract_titles(body, title_re): + titles = [] + for title, _ in title_re.findall(body): + h = title.strip() + level = 1 + while h[level:level+1] == '=': level = level+1 + depth = min(5,level) + title_text = h[level:-level].strip() + titles.append((title_text, level)) + return titles + +def execute(macro, text, args_re=re.compile(_args_re_pattern), title_re=re.compile(_title_re, re.M), called_by_toc=0): + request = macro.request + _ = request.getText + + qnumber = choice(range(1, 10, 1)) + text = u'QuestionnaireCrans/Question\d+[a-z]?$,, from="^= Question =$", to="^----$"' + + # return immediately if getting links for the current page + if request.mode_getpagelinks: + return '' + + # parse and check arguments + args = args_re.match(text) + if not args: + return (_sysmsg % ('error', _('Invalid include arguments "%s"!')) % (text,)) + + # Search the pages and return the results + query = search.QueryParser(regex=1).parse_query(args.group('name')) + results = search.searchPages(request, query) + results.sortByPagename() + pagelist = [results.hits[qnumber].page_name] + + # prepare including page + result = [] + print_mode = macro.form.has_key('action') and macro.form['action'][0] == "print" + this_page = macro.formatter.page + if not hasattr(this_page, '_macroInclude_pagelist'): + this_page._macroInclude_pagelist = {} + + skipitems = 0 + if args.group("skipitems"): + skipitems = int(args.group("skipitems")) + titlesonly = args.group('titlesonly') + editlink = args.group('editlink') + + # iterate over pages + for inc_name in pagelist: + if not request.user.may.read(inc_name): + continue + if this_page._macroInclude_pagelist.has_key(inc_name): + result.append(u'

Recursive include of "%s" forbidden

' % (inc_name,)) + continue + if skipitems: + skipitems -= 1 + continue + fmt = macro.formatter.__class__(request, is_included=True) + fmt._base_depth = macro.formatter._base_depth + inc_page = Page(request, inc_name, formatter=fmt) + inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist + + # check for "from" and "to" arguments (allowing partial includes) + body = inc_page.get_raw_body() + '\n' + from_pos = 0 + to_pos = -1 + from_re = args.group('from') + if from_re: + try: + from_match = re.compile(from_re, re.M).search(body) + except re.error, e: + ##result.append("*** fe=%s ***" % e) + from_match = re.compile(re.escape(from_re), re.M).search(body) + if from_match: + from_pos = from_match.end() + else: + result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re) + to_re = args.group('to') + if to_re: + try: + to_match = re.compile(to_re, re.M).search(body, from_pos) + except re.error: + to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos) + if to_match: + to_pos = to_match.start() + else: + result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re) + + if titlesonly: + newbody = [] + levelstack = [] + for title, level in extract_titles(body[from_pos:to_pos], title_re): + if levelstack: + if level > levelstack[-1]: + result.append(macro.formatter.bullet_list(1)) + levelstack.append(level) + else: + while levelstack and level < levelstack[-1]: + result.append(macro.formatter.bullet_list(0)) + levelstack.pop() + if not levelstack or level != levelstack[-1]: + result.append(macro.formatter.bullet_list(1)) + levelstack.append(level) + else: + result.append(macro.formatter.bullet_list(1)) + levelstack.append(level) + result.append(macro.formatter.listitem(1)) + result.append(inc_page.link_to(request, title)) + result.append(macro.formatter.listitem(0)) + while levelstack: + result.append(macro.formatter.bullet_list(0)) + levelstack.pop() + continue + + if from_pos or to_pos != -1: + inc_page.set_raw_body(body[from_pos:to_pos], modified=True) + ##result.append("*** f=%s t=%s ***" % (from_re, to_re)) + ##result.append("*** f=%d t=%d ***" % (from_pos, to_pos)) + + if called_by_toc: + result.append(inc_page.get_raw_body()) + continue + + if not hasattr(request, "_Include_backto"): + request._Include_backto = this_page.page_name + + # do headings + level = None + if args.group('heading') and args.group('hquote'): + heading = args.group('htext') or inc_page.split_title(request) + level = 1 + if args.group('level'): + level = int(args.group('level')) + if print_mode: + result.append(macro.formatter.heading(1, level) + + macro.formatter.text(heading) + + macro.formatter.heading(0, level)) + else: + import sha + from MoinMoin import config + # this heading id might produce duplicate ids, + # if the same page is included multiple times + # Encode stuf we feed into sha module. + pntt = (inc_name + heading).encode(config.charset) + hid = "head-" + sha.new(pntt).hexdigest() + request._page_headings.setdefault(pntt, 0) + request._page_headings[pntt] += 1 + if request._page_headings[pntt] > 1: + hid += '-%d'%(request._page_headings[pntt],) + result.append( + #macro.formatter.heading(1, level, hid, + # icons=edit_icon.replace(' 1: + this_page._macroInclude_pagelist[inc_name] = \ + this_page._macroInclude_pagelist[inc_name] - 1 + else: + del this_page._macroInclude_pagelist[inc_name] + + # if no heading and not in print mode, then output a helper link + if editlink and not (level or print_mode): + result.extend([ + '', + ]) + # XXX page.link_to is wrong now, it escapes the edit_icon html as it escapes normal text + + # return include text + return ''.join(result) + +# vim:ts=4:sw=4:et diff --git a/wiki-lenny/local/macro/RandomQuoteNum.py b/wiki-lenny/local/macro/RandomQuoteNum.py new file mode 100644 index 00000000..5b237729 --- /dev/null +++ b/wiki-lenny/local/macro/RandomQuoteNum.py @@ -0,0 +1,57 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - RandomQuote Macro + + Selects a random quote from FortuneCookies or a given page. + + Usage: + [[RandomQuote()]] + [[RandomQuote(WikiTips)]] + + Comments: + It will look for list delimiters on the page in question. + It will ignore anything that is not in an "*" list. + + @copyright: 2002-2004 by Jürgen Hermann + @license: GNU GPL, see COPYING for details. + + Originally written by Thomas Waldmann. + Gustavo Niemeyer added wiki markup parsing of the quotes. +""" + +import random, StringIO +from MoinMoin.Page import Page, wikiutil + +Dependencies = ["time"] + +def execute(macro, args): + _ = macro.request.getText + + pagename = args or 'FortuneCookies' + if macro.request.user.may.read(pagename): + page = Page(macro.request, pagename) + raw = page.get_raw_body() + else: + raw = "" + + # this selects lines looking like a list item + # !!! TODO: make multi-line quotes possible (optionally split by "----" or something) + quotes = raw.splitlines() + quotes = [quote.strip() for quote in quotes] + quotes = [quote[2:] for quote in quotes if quote.startswith('1. ')] + + if not quotes: + return (macro.formatter.highlight(1) + + _('No quotes on %(pagename)s.') % {'pagename': pagename} + + macro.formatter.highlight(0)) + + quote = random.choice(quotes) + page.set_raw_body(quote, 1) + out = StringIO.StringIO() + macro.request.redirect(out) + page.send_page(macro.request, content_only=1, content_id="RandomQuote_%s" % wikiutil.quoteWikinameFS(page.page_name) ) + quote = out.getvalue() + macro.request.redirect() + + return quote + diff --git a/wiki-lenny/local/macro/SubscribeTo.py b/wiki-lenny/local/macro/SubscribeTo.py new file mode 100644 index 00000000..5f6e6e34 --- /dev/null +++ b/wiki-lenny/local/macro/SubscribeTo.py @@ -0,0 +1,157 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - Automaticaly subscribe user(s) on save + + [[SubscribeTo(UserName1[,+GroupName1[,-UserName2]])]] + + Will add those users and/or group of users as subscribers while saving the + page. These users are not subscribed for templates nor while preview the + page. To subscribe to this template the FQTN (full-qualified template name) + has to be specified as one of the parameters. + + Using (-) and (+) it's possible to create a flexible list of users will + be subscribed to this page. E.g. select a long group and remove with (-) + some group members. Or select a short group and extend the list by adding + (+) additional users. By default users are added if no (-) or (+) is + specified. (-) does not remove the subscribtion for the specified user. + (-) does not change the status of the subscription for the specified user. + + @copyright: (C) 2005,2006 Raphael Bossek + @license: GNU GPL 2, see COPYING for details + @version: 20060402 + @url: http://www.solutions4linux.de/cgi-bin/view/Main/MoinMoinSubscribeTo +""" + +from MoinMoin import user +import re + +def execute (macro, args): + _ = macro.request.getText + unknownuname = {} + missingemail = {} + outofdateversion = 0 + result = u'' + allusers = re.split (r'[,;\s]+', args) + subscribeto = {} + page_name = macro.request.page.page_name + is_preview = macro.form.has_key ('button_preview') + p_warning = u'

' + macro.formatter.icon ("info") + u' ' + p_notice = u'

' + macro.formatter.icon ("info") + u' ' + p_info = u'

' + macro.formatter.icon ("info") + u' ' + # TODO: Should be compiled only once, and cached in cfg + group_re = re.compile (macro.cfg.page_group_regex, re.UNICODE) + # By default templates are not subsribed. This can be changed by + # specifing the FQTN as parameter. + is_template = re.search (macro.cfg.page_template_regex, page_name, re.UNICODE) + # Proceed the list in the same order as specified by the user. + # This allow us to work with groups and users in the same way + # as specifing all members of a group. + for uname in allusers: + # Skip empty names + if not uname: + continue + # Determine what to do with the user/group members. + if uname[:1] == '-': + uname = uname[1:] + remove_action = True + else: + if uname[:1] == '+': + uname = uname[1:] + remove_action = False + + # It's a special feature. If the FQTN (full-qualified template name) + # is one of the parameters we allow to subscribe to this template too. + if remove_action == False and uname == page_name: + is_template = False + continue + + members = [] + # Distinguish between user and group. Create a list of + # users which has to be subscribed to. + if group_re.search (uname): + # Recursively expand groups + groupdict = macro.request.dicts + if groupdict.hasgroup (uname): + members = groupdict.members (uname) + else: + unknownuname[uname] = 1 + else: + members = [uname] + + # Go through all members and proceed with the same action. + for uname in members: + uid = user.getUserId (macro.request, uname) + if not uid: + # Only if this user has to be added and does not exists put + # his name in our unknwonuname list. Otherwise the use does + # not matter. + if remove_action == False: + unknownuname[uname] = 1 + # If this user was added before but we know now that should + # be skipped we update the unknownuname list afterward. + else: + if uname in subscribeto: + del subscribeto[uname] + if uname in unknownuname: + del unknownuname[uname] + else: + thisuser = user.User (macro.request, id = uid) + if not thisuser.email: + missingemail[uname] = 1 + else: + subscribeto[uname] = (thisuser, remove_action) + # MoinMoin compatibility check + if not 'subscribePage' in dir (thisuser) and not 'subscribe' in dir (thisuser): + outofdateversion = 1 + break + if not outofdateversion: + if unknownuname: + result += p_warning + _(u'This user(s)/group(s) are unknown by now: %s') % u', '.join (unknownuname.keys()) + u'

' + if missingemail: + result += p_warning + _(u'Follwing users(s) missing an email address in their profile: %s') % u', '.join (missingemail.keys()) + u'

' + if subscribeto: + addeduname = [] + faileduname = [] + subscribeduname = [] + subscribe_status = (1 == 1) + if not is_template: + for uname, (thisuser, remove_action) in subscribeto.iteritems(): + # Do not modify the subscribtion of this usser. + if remove_action == True: + continue + # Do _not_ subscribe these users while preview the page + if not thisuser.isSubscribedTo ([page_name]): + if not is_preview: + # Support for MoinMoin 1.3 + if 'subscribePage' in dir (thisuser): + subscribe_status = thisuser.subscribePage (page_name) + if subscribe_status: + thisuser.save() + # Support for MoinMoin 1.5 + elif 'subscribe' in dir (thisuser): + subscribe_status = thisuser.subscribe (page_name) + else: + outofdateversion = 1 + break + if not subscribe_status: + faileduname.append (uname) + else: + addeduname.append (uname) + else: + subscribeduname.append (uname) + else: + result += p_notice + _(u'This template will not be subscribed!') + u' ' + _(u'Follwing user(s)/group(s) are remembered to be subscribed later with a regular page: %s') % u', '.join (subscribeto.keys()) + u'

' + if addeduname: + result += p_info + _(u'Following new user(s) will be subscribed to %s before saving: %s') % (page_name, u', '.join (addeduname)) + u'

' + if subscribeduname: + result += p_info + _(u'Following user(s) are already subsribed to %s: %s') % (page_name, u', '.join (subscribeduname)) + u'

' + if faileduname: + result += p_warning + _(u'This user(s) failed to subscribe to: %s') % u', '.join (faileduname) + u'

' + + if outofdateversion: + result += p_warning + _(u'Sorry, out-of-date version of SubscribeTo marcro installed! Functionality disabled until an update occurs.') + u'

' + + if is_preview: + return result + return u'' + diff --git a/wiki-lenny/local/macro/TableOfContents.py b/wiki-lenny/local/macro/TableOfContents.py new file mode 100644 index 00000000..3242c7d4 --- /dev/null +++ b/wiki-lenny/local/macro/TableOfContents.py @@ -0,0 +1,186 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - TableOfContents Macro + + Optional integer argument: maximal depth of listing. + + @copyright: 2000, 2001, 2002 by Jürgen Hermann + @copyright: 2006 by Grégoire Détrez + @license: GNU GPL, see COPYING for details. +""" + +import re, sha +from MoinMoin import config, wikiutil + +#Dependencies = ["page"] +Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks + +# from macro Include (keep in sync!) +_arg_heading = r'(?P,)\s*(|(?P[\'"])(?P.+?)(?P=hquote))' +_arg_level = r',\s*(?P\d*)' +_arg_from = r'(,\s*from=(?P[\'"])(?P.+?)(?P=fquote))?' +_arg_to = r'(,\s*to=(?P[\'"])(?P.+?)(?P=tquote))?' +_arg_sort = r'(,\s*sort=(?P(ascending|descending)))?' +_arg_items = r'(,\s*items=(?P\d+))?' +_arg_skipitems = r'(,\s*skipitems=(?P\d+))?' +_arg_titlesonly = r'(,\s*(?Ptitlesonly))?' +_arg_editlink = r'(,\s*(?Peditlink))?' +_args_re_pattern = r'^(?P[^,]+)(%s(%s)?%s%s%s%s%s%s%s)?$' % ( + _arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items, + _arg_skipitems, _arg_titlesonly, _arg_editlink) + +# from Include, too, but with extra htext group around header text +_title_re = r"^(?P(?P=+)\s(?P.*)\s(?P=hmarker))$" + +class TableOfContents: + """ + TOC Macro wraps all global variables without disturbing threads + """ + + def __init__(self, macro, args): + self.macro = macro + + self.inc_re = re.compile(r"^\[\[Include\((.*)\)\]\]") + self.arg_re = re.compile(_args_re_pattern) + self.head_re = re.compile(_title_re) # single lines only + self.pre_re = re.compile(r'\{\{\{.+?\}\}\}', re.S) + + self.result = [] + self.baseindent = 0 + self.indent = 0 + self.lineno = 0 + self.titles = {} + + self.include_macro = None + + try: + self.mindepth = int(macro.request.getPragma('section-numbers', 1)) + except (ValueError, TypeError): + self.mindepth = 1 + + try: + self.maxdepth = max(int(args), 1) + except (ValueError, TypeError): + self.maxdepth = 99 + + def IncludeMacro(self, *args, **kwargs): + if self.include_macro is None: + self.include_macro = wikiutil.importPlugin(self.macro.request.cfg, + 'macro', "Include") + return self.pre_re.sub('',apply(self.include_macro, args, kwargs)).split('\n') + + def run(self): + f = self.macro.formatter + r = self.result + try: + # Wikipedia-style table of contents + r.append(f.open('div', True, {'id': 'tableOfContents'})) + r.append(f.open('h2', False, {'id': 'toctitle'})) + r.append(f.text(u'Sommaire')) + r.append(f.close('h2', True)) + r.append(f.open('div', True, {'id': 'tableOfContentsList'})) + except: + pass + + self.process_lines(self.pre_re.sub('',self.macro.parser.raw).split('\n'), + self.macro.formatter.page.page_name) + # Close pending lists + for i in range(self.baseindent, self.indent): + self.result.append(self.macro.formatter.listitem(0)) + self.result.append(self.macro.formatter.number_list(0)) + + try: + r.append(f.close('div', True)) + r.append(f.close('div', True)) + r.append(f.open('div', False, {'class': 'visualClear'})) + r.append(f.close('div', True)) + r.append(f.open('script', False, + {'type': 'text/javascript', + 'src': '/wiki/common/toc/toc.js'})) + r.append(f.close('script', True)) + except: + pass + + return u''.join(r) + + def process_lines(self, lines, pagename): + for line in lines: + # Filter out the headings + self.lineno = self.lineno + 1 + match = self.inc_re.match(line) + if match: + # this is an [[Include()]] line. + # now parse the included page and do the work on it. + + ## get heading and level from Include() line. + tmp = self.arg_re.match(match.group(1)) + if tmp and tmp.group("name"): + inc_pagename = tmp.group("name") + else: + # no pagename? ignore it + continue + if tmp.group("heading"): + if tmp.group("htext"): + heading = tmp.group("htext") + else: + heading = inc_pagename + if tmp.group("level"): + level = int(tmp.group("level")) + else: + level = 1 + inc_page_lines = ["%s %s %s" %("=" * level, heading, "=" * level)] + else: + inc_page_lines = [] + + inc_page_lines = inc_page_lines + self.IncludeMacro(self.macro, match.group(1), called_by_toc=1) + + self.process_lines(inc_page_lines, inc_pagename) + else: + self.parse_line(line, pagename) + + def parse_line(self, line, pagename): + # FIXME this also finds "headlines" in {{{ code sections }}}: + match = self.head_re.match(line) + if not match: return + title_text = match.group('htext').strip() + pntt = pagename + title_text + self.titles.setdefault(pntt, 0) + self.titles[pntt] += 1 + + # Get new indent level + newindent = len(match.group('hmarker')) + if newindent > self.maxdepth: return + if newindent < self.mindepth: return + if not self.indent: + self.baseindent = newindent - 1 + self.indent = self.baseindent + + # Close lists + for i in range(0,self.indent-newindent): + self.result.append(self.macro.formatter.listitem(0)) + self.result.append(self.macro.formatter.number_list(0)) + + # Open Lists + for i in range(0,newindent-self.indent): + self.result.append(self.macro.formatter.number_list(1)) + + # Add the heading + unique_id = '' + if self.titles[pntt] > 1: + unique_id = '-%d' % (self.titles[pntt],) + + if self.indent == newindent: + self.result.append(self.macro.formatter.listitem(0)) + + self.result.append(self.macro.formatter.listitem(1)) + self.result.append(self.macro.formatter.anchorlink(1, + "head-" + sha.new(pntt.encode(config.charset)).hexdigest() + unique_id) + + self.macro.formatter.text(title_text) + + self.macro.formatter.anchorlink(0)) + + # Set new indent level + self.indent = newindent + +def execute(macro, args): + toc=TableOfContents(macro,args) + return toc.run() diff --git a/wiki-lenny/local/macro/TerminalSsh.py b/wiki-lenny/local/macro/TerminalSsh.py new file mode 100644 index 00000000..2017503e --- /dev/null +++ b/wiki-lenny/local/macro/TerminalSsh.py @@ -0,0 +1,53 @@ +Dependencies = ["Time"] + +class ssh: + settings = { + 'protocol' : "ssh2", + 'server' : 'ssh.crans.org', + 'port' : '22', + "auth-method" : "keyboard-interactive", + "bg-color" : "black", + "fg-color" : "white", + "cursor-color" : "yellow", + "menus" : "pop3", + "geometry" : "94x32", + "allow-new-server" : "false", + } + + #appletLocation = "/wiki/applets/mindterm.jar" + appletLocation = "https://ssh.crans.org/mindterm.jar" + + def parseArgs(self, args): + argList = args.split(u',') + + for anArg in argList: + try: + key = anArg.split(u'=')[0] + value = anArg.split(u'=')[1] + self.settings[key] = value + except:pass + + def formatParams(self): + html = [] + for key, value in self.settings.items(): + html.append(u'' % (key, value)) + return u'\n'.join(html) + + def __init__(self, args): + self.parseArgs(args) + + def run(self): + html = [ + u'

', + u'' % self.appletLocation, + self.formatParams(), + u'', + u'

', + ] + return u'\n'.join(html) + +def execute(macro, args): +# return macro.formatter.text("I got these args from a macro %s: %s" % +# (str(macro), args)) + o = ssh(args) + return o.run()